I've been working a lot with the DateTime class
and recently ran into what I thought was a bug when adding months. After a bit of research, it appears that it wasn't a bug, but instead working as intended. According to the documentation found here:
Example #2 Beware when adding or subtracting months
<?php $date = new DateTime('2000-12-31'); $date->modify('+1 month'); echo $date->format('Y-m-d') . "\n"; $date->modify('+1 month'); echo $date->format('Y-m-d') . "\n"; ?>
The above example will output: 2001-01-31 2001-03-03
Can anyone justify why this isn't considered a bug?
Furthermore does anyone have any elegant solutions to correct the issue and make it so +1 month will work as expected instead of as intended?
The date_sub() is an inbuilt function in PHP which is used to subtract some days, months, years, hours, minutes, and seconds from given date. The function returns a DateTime object on success and returns FALSE on failure.
The strtotime() function parses an English textual datetime into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 GMT). Note: If the year is specified in a two-digit format, values between 0-69 are mapped to 2000-2069 and values between 70-100 are mapped to 1970-2000.
The current behavior is correct. The following happens internally:
+1 month
increases the month number (originally 1) by one. This makes the date 2010-02-31
.
The second month (February) only has 28 days in 2010, so PHP auto-corrects this by just continuing to count days from February 1st. You then end up at March 3rd.
To get what you want is by: manually checking the next month. Then add the number of days next month has.
I hope you can yourself code this. I am just giving what-to-do.
To obtain the correct behavior, you can use one of the PHP 5.3's new functionality that introduces the relative time stanza first day of
. This stanza can be used in combination with next month
, fifth month
or +8 months
to go to the first day of the specified month. Instead of +1 month
from what you're doing, you can use this code to get the first day of next month like this:
<?php $d = new DateTime( '2010-01-31' ); $d->modify( 'first day of next month' ); echo $d->format( 'F' ), "\n"; ?>
This script will correctly output February
. The following things happen when PHP processes this first day of next month
stanza:
next month
increases the month number (originally 1) by one. This makes the date 2010-02-31.
first day of
sets the day number to 1
, resulting in the date 2010-02-01.
Here is another compact solution entirely using DateTime methods, modifying the object in-place without creating clones.
$dt = new DateTime('2012-01-31'); echo $dt->format('Y-m-d'), PHP_EOL; $day = $dt->format('j'); $dt->modify('first day of +1 month'); $dt->modify('+' . (min($day, $dt->format('t')) - 1) . ' days'); echo $dt->format('Y-m-d'), PHP_EOL;
It outputs:
2012-01-31 2012-02-29
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With