Description
Description
The following code:
<?php
$og = new DateTime(date('2025-03-31'));
$d = clone( $og );
$one_month = new DateInterval('P1M');
$next_month = $d->add($one_month);
echo "Start Date: " . $og->format('Y-m-d') . "\n";
echo "Next Month: " . $next_month->format('Y-m-d');
Resulted in this output:
Start Date: 2025-03-31
Next Month: 2025-05-01
But I expected this output instead:
Start Date: 2025-03-31
Next Month: 2025-04-30
For comparison in JS Temporal:
> now = Temporal.Now.zonedDateTimeISO()
> now.toString()
"2025-03-31T14:19:39.108140159+01:00[Europe/London]"
> now.add('P1M').toString()
"2025-04-30T14:19:39.108140159+01:00[Europe/London]"
Month durations / interval modifications should be able to account for calendar days per ISO 8601 and consistently change the month only without carrying excess days over and returning a date in the following month.
In the ISO8601 spec:
month
duration of 28, 29, 30 or 31 calendar days depending on the start and/or the end of the corresponding time
interval within the specific calendar month
NOTE 1 The term “month” applies also to the duration of any time interval which starts at a certain time of day at a
certain calendar day of the calendar month and ends at the same time of day at the same calendar day of the next
calendar month, if it exists. In other cases the ending calendar day has to be agreed on.
NOTE 2 In certain applications a month is considered as a duration of 30 calendar days.
PHP Version
8.4.5
Operating System
No response