|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-04-16 10:37 UTC] pawaroti at gmail dot com
Description:
------------
Adding 1 month using DateInterval('P1M') sets date to 2015-03-03 if adding from DateTime('2015-01-31')
+1 month = 2015-03-03
+2 months = 2015-03-31
+3 months = 2015-05-01
+4 months = 2015-05-31
+5 months = 2015-07-01
+6 months = 2015-07-31
+7 months = 2015-08-31
+8 months = 2015-10-01
+9 months = 2015-10-31
+10 months = 2015-12-01
+11 months = 2015-12-31
+12 months = 2016-01-31
BEFORE:
object(DateTime)[5]
public 'date' => string '2015-01-31 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Warsaw' (length=13)
AFTER
object(DateTime)[5]
public 'date' => string '2015-03-03 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Warsaw' (length=13)
INTERVAL
object(DateInterval)[6]
public 'y' => int 0
public 'm' => int 1
public 'd' => int 0
public 'h' => int 0
public 'i' => int 0
public 's' => int 0
public 'weekday' => int 0
public 'weekday_behavior' => int 0
public 'first_last_day_of' => int 0
public 'invert' => int 0
public 'days' => boolean false
public 'special_type' => int 0
public 'special_amount' => int 0
public 'have_weekday_relative' => int 0
public 'have_special_relative' => int 0
Test script:
---------------
for($i=0; $i<=12; $i++)
{
$data = new DateTime('2015-01-31');
echo $data->add(new DateInterval('P'.$i.'M'))->format('Y-m-d').'<br />';
}
Expected result:
----------------
2015-02-28
2015-03-31
2015-04-30
2015-05-31
2015-06-30
2015-07-31
2015-08-31
2015-09-30
2015-10-31
2015-11-30
2015-12-31
2016-01-31
Actual result:
--------------
2015-03-03
2015-03-31
2015-05-01
2015-05-31
2015-07-01
2015-07-31
2015-08-31
2015-10-01
2015-10-31
2015-12-01
2015-12-31
2016-01-31
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2026 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 06 19:00:01 2026 UTC |
P1M means "increment the month number by 1". Jan 31 + 1 month = Feb 31, which is invalid and overflows into March, becoming Mar 3. Similarly for other months with <31 days. You need to decide what result you want to get, understand why you want to get it, and then write code to support it. You may find that the logic is easier to express using the procedural functions. For example, if you wanted to use the last day of the month if the date overflowed, // extract month, day, and year components $start = date_parse("2015-01-31"); // use month+1 and allow for overflow $target = mktime(0, 0, 0, $start["month"] + 1, $start["day"], $start["year"]); // end day < start day promises that the date must have overflowed if (getdate($target)["mday"] < $start["day"]) { // use underflow with month+2 $target = mktime(0, 0, 0, $start["month"] + 2, 0, $start["year"]); } http://3v4l.org/Y3CHG