PHP date() and strtotime() return wrong months on 31st
Asked Answered
W

4

15

I'm using date()and strtotime() functions to display the next 3 months in a dropdown list.

PHP Code:

   echo date("m/Y",strtotime("+0 months")); 
   echo date("m/Y",strtotime("+1 months"));
   echo date("m/Y",strtotime("+2 months")); 

However, if the script is running when the server date is on 30th or 31st, the next month, which is Feburary, will be displayed as March instead. i.e. the script above is supposed to return

01/2012
02/2012
03/2012

But, instead of that, it actually displays

01/2012
03/2012
03/2012

that is because Feburary doesn't have 30th or 31st, so the script translates "31/02" into "01/03".

I have read the strtotime() page on php.net, this problem has been raised, but there has not been any useful solutions. So can anyone please help me to find a simple way to solve this problem? Thanks in advance!

Wendell answered 30/1, 2012 at 1:52 Comment(1)
A
31

As mentioned within the documentation, you should pass the date for the first day of the current month as the second parameter to the strtotime() function:

$base = strtotime(date('Y-m',time()) . '-01 00:00:01');
echo date('m/Y',strtotime('+0 month', $base));
echo date('m/Y',strtotime('+1 month', $base));
echo date('m/Y',strtotime('+2 month', $base));

See that it works: http://ideone.com/eXis9

01/2012

02/2012

03/2012

Armillary answered 30/1, 2012 at 1:57 Comment(1)
Considering $base = strtotime('2016-12-31' . '-01 00:00:01'); the solution sill prints February 2 times for +2 month and +3 monthZither
U
12

Try using "first day of" in your strtotime, like this:

strtotime("first day of +1 month");

This will fix dates ( in the event today was Jan 30th ) such as 02-30 (Yields march 2nd) by converting it to 02-01 (Feb 1st) which then gives you the correct month. It's a little cleaner than other methods, and easier to remember.

Unexpected answered 31/5, 2012 at 16:43 Comment(3)
Very elegant solution.Roldan
Doesn't work with FIRST DAY OF -2 MONTHS on the 31st. base is importantAsiatic
Shrugg - Today on 2018-05-31, echo date('Y-m-d', strtotime('FIRST DAY OF -2 MONTH')); yields -> 2018-03-01. 5-2 = 3. Seems to work, what example did you have that did not?Unexpected
L
5
echo date('m/Y', strtotime(date('Y-m') . '-01 +2 months'));

Just hard-code it to be the first of the month.

Laboratory answered 30/1, 2012 at 1:57 Comment(0)
E
0

Don't use strtotime() for getting offset date by month(s). It works properly only in PHP 5.3+. The best way to solve such problem is using mktime(). Below is a sample code:

function getOffsetByMonths($nMonths, $nNow = 0) {
    if ($nNow)
        return mktime(0, 0, 0, date('n', $nNow)+ $nMonths, 1, date('Y', $nNow));
    else
        return mktime(0, 0, 0, date('n')+ $nMonths);
}
$nNow = mktime(0, 0, 0, 1, 31, 2013);
echo "Now: ". date("Y-m-d", $nNow).
"<br>(Now - 1 month): ". date("Y-m", getOffsetByMonths(-1, $nNow)). "-xx".
"<br>(Now - 2 month): ". date("Y-m", getOffsetByMonths(-2, $nNow)). "-xx".
"<br>(Now - 3 month): ". date("Y-m", getOffsetByMonths(-3, $nNow)). "-xx";
Europe answered 28/2, 2013 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.