0

I have a strange problem that I have never encountered with PHP before when using their strtotime() function.

$original = strtotime('2015-12-31 12:34:56');
$time = strtotime('+ 2 month', $original);
echo date('m/d/y H:i:s', $original),'<br>',date('m/d/y H:i:s', $time);

What I expect to get as output:

12/31/15 12:34:56
02/29/16 12:34:56

What I actually get as output:

12/31/15 12:34:56
03/02/16 12:34:56

How can I account for this calculation error? After quite a bit of investigation I realize that PHP uses an average of 30.5 days to do calculations like this. I don't really care so much about the "WHY" this happens, but rather what I can do to account for it. I have some ideas in mind that involve writing a wrapper for strtotime() when involving month calculations, but it seems like a convoluted approach...

There is an existing answer for this question but the time component is not mentioned in the question (only a date), hence I don't consider this question a duplicate of that one. In addition, I am mainly seeking an improvement to the way we handle such an issue, not necessarily a solution posted for the aforementioned question. If, however, I am wrong to do this then you are welcome to remove this question :(

Community
  • 1
  • 1
CzechErface
  • 326
  • 2
  • 12
  • Because a month isn't a fixed length.... PHP doesn't give you "last day of the month two months hence", it takes an arbitrary month length that will work in most (but not all) circumstances.... if you want that, add 2 months to the first day of the month, then request last date of that month – Mark Baker Mar 01 '16 at 23:26

2 Answers2

2

February doesn't have 31 days, so the overflowing days will pushed to march. You can check the effect if you change the year from 2015 to 2014 and execute the code again. The result is 2015-03-03 (February has 28 days in 2015)

Tyr
  • 2,810
  • 1
  • 12
  • 21
2

If you want to get the last date you could use this over-/underflowing behaviour the other way:

$original = new DateTime('2015-12-31');
$modified = clone $original;
$modified->modify('+2 months');
$modified->setDate($modified->format('Y'), $modified->format('m'), 0);

echo $original->format('m/d/y H:i:s') . "<br>" .$modified->format('m/d/y H:i:s');

or simpler

$date = explode('-', '2015-12-31');
$modified = new DateTime();
$modified->setDate($date[0], $date[1]+3, 0);

Not the prettiest solution, but it works.

WhoIsJohnDoe
  • 338
  • 1
  • 8
  • Sorry if it sounds rude, but we aren't your personal coding army, so if you receive a working solution, accept it and improve it by yourself. Date calculations are a little bit messy in PHP, so there isn't an easy solution for this issue: http://stackoverflow.com/questions/14584115/php-strtotime-1-month-adding-an-extra-month – Tyr Mar 01 '16 at 23:56