admin管理员组文章数量:1287879
Let's say I need to change a datetime object by adding or subtracting some months.
How to avoid the well known PHP month calculations?
$monthstoadd=-1;
//today is 2025-01-24
$date=new DateTime("last day of last month");
echo $date->format('Y-m-d');
//out: is 2024-12-31
$date->modify(($monthstoadd>0?'+':'').$monthstoadd.' month');
echo $date->format('Y-m-d');
//out: is 2024-12-01
Starting from last day of month, I expect to get always the last day of the month (floor).
Is there any way to modify a date with this preference?
mysql> SELECT '2025-01-30' + interval 1 month
-> '2025-02-28'
pgsql> SELECT date '2025-01-30' + interval '1 month';
-> '2025-02-28 00:00:00'
sqlite> SELECT date('2025-01-30', '+1 month');
-> '2025-03-02'
Let's say I need to change a datetime object by adding or subtracting some months.
How to avoid the well known PHP month calculations?
$monthstoadd=-1;
//today is 2025-01-24
$date=new DateTime("last day of last month");
echo $date->format('Y-m-d');
//out: is 2024-12-31
$date->modify(($monthstoadd>0?'+':'').$monthstoadd.' month');
echo $date->format('Y-m-d');
//out: is 2024-12-01
Starting from last day of month, I expect to get always the last day of the month (floor).
Is there any way to modify a date with this preference?
mysql> SELECT '2025-01-30' + interval 1 month
-> '2025-02-28'
pgsql> SELECT date '2025-01-30' + interval '1 month';
-> '2025-02-28 00:00:00'
sqlite> SELECT date('2025-01-30', '+1 month');
-> '2025-03-02'
Share
Improve this question
edited Jan 27 at 18:25
hakre
198k55 gold badges446 silver badges854 bronze badges
Recognized by PHP Collective
asked Jan 24 at 13:05
TobiaTobia
9,50629 gold badges120 silver badges242 bronze badges
12
- 4 adding months is a tricky business. When you're adding 1 month to January, 30th, which date you expect? – Your Common Sense Commented Jan 24 at 13:10
- 1 Seriously, it's tricky. Now add one month to 28th Feb. Is it 30th March or 28th? Do you want +1+1 to equal +2? – Álvaro González Commented Jan 24 at 17:21
- 1 "Starting from last day of month, I expect to get always the last day of the month" and "Now add one month to 28th Feb…It's 28th march" - aren’t these two in conflict? – Chris Haas Commented Jan 26 at 13:49
- 1 For your case I would go into percentage base solution - per given month define what it 100% and apply the resulted percentage to the next month. Feb 28 (100% of non leap year) +1 month = March 31 (100%). As for rounding it up or down, you will have to decide it yourself :]. – Mortimer Commented Jan 27 at 12:50
- 1 Just for reference, in the MySQL documentation they say "If you add MONTH... and the resulting date has a day that is larger than the maximum day for the new month, the day is adjusted to the maximum days in the new month:" – Chris Haas Commented Jan 27 at 14:01
1 Answer
Reset to default 0So you like the way MySQL is doing it, ¹ and then you stumble over how the modify expressions work in PHP:
$start = new DateTimeImmutable("2025-01-30");
echo min(
$start->modify('last day of next month'),
$start->modify('+1 month')
)->format('Y-m-d'), PHP_EOL; // 2025-02-28
Let's recap how MySQL is doing it: ¹
$addXMonths = static fn(string $date, int $months) => 1 > $months
? throw new InvalidArgumentException(sprintf('$months: 1 > %d', $months))
: (static fn(array $p) => sprintf('%04d-%02d-%02d',
($year = $p['year'] + intdiv($months, 12)),
($month = $p['month'] + $months % 12),
min($p['day'], date_create("$year-$month-01")->format('t'))
))(date_parse($date));
echo $addXMonths('2025-01-30', 1), PHP_EOL; // 2025-02-28
¹ From Temporal Intervals (mysql.com):
If you add
MONTH
,YEAR_MONTH
, orYEAR
and the resulting date has a day that is larger than the maximum day for the new month, the day is adjusted to the maximum days in the new month:mysql> SELECT DATE_ADD('2019-01-30', INTERVAL 1 MONTH); -> '2019-02-28'
本文标签: phpHow to subtractadd yearsmonth intervals to a date (like MySQL INTERVAL expression)Stack Overflow
版权声明:本文标题:php - How to subtractadd yearsmonth intervals to a date (like MySQL INTERVAL expression) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738416520a2085613.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论