Monthly Archives: November 2011

PHP strtotime WTF!

So I just spent almost a day chasing a (what I thought it was) a bug in my code regarding dates.

I needed to add a month to a specific date  so I can bill ongoing contracts, but the returned date sometimes where full “calendar” months other times it was 31 days.

Let me show:

echo date("Y-m-d", strtotime("+1 month 2011-11-21"));
returns: 2011-12-21 // appears to be right

echo date("Y-m-d", strtotime("+1 month 2011-11-30"));
returns: 2011-12-30 // wtf? but I wanted 2011-12-31

echo date("Y-m-d", strtotime("+1 month 2011-12-15"));
returns:  2012-01-15 // hum? that is right

echo date("Y-m-d", strtotime("+1 month 2012-01-31"));
returns: 2012-03-02 // wtf? I wanted 2012-02-29

echo date("Y-m-d", strtotime("+1 month 2012-01-01"));
returns: 2012-02-01 // oh! that's right

echo date("Y-m-d", strtotime("+1 month 2012-02-01"));
returns: 2012-03-01 // sigh... That's right to what's going on here?

As you can see above sometimes PHP return full calendar months other 31 days. Fortunately there’s a pattern:

The way I see it if the day is not in the end of the month PHP will add a calendar month if it’s in the end of the month PHP will add the number of days that the current month has.

So if you want to make sure PHP always adds a calendar month to your date this is how I did it:

$tmp_date1 = strtotime("+1 day", strtotime("2012-01-31"));
$tmp_date2 = strtotime("+1 month", $tmp_date1);
$final_date = date('Y-m-d', strtotime("-1 day", $tmp_date2));

This ensures that if your date is in the end of the month strtotime will make calculation with the beginning of the month that way full calendar months will be added instead of number of days that current month has.

Reddit discussion about this