This was working fine yesterday with no changes to the code.
echo date(\"M\", strtotime(\"-3 month\", time()) );
echo date(\"M\", strtotime(\"-2 month\", tim
This is known and expected behavior. The reason for this is that a month is a relative date with no fixed length. From http://www.gnu.org/software/tar/manual/html_node/Relative-items-in-date-strings.html#SEC120
The unit of time displacement may be selected by the string ‘year’ or ‘month’ for moving by whole years or months. These are fuzzy units, as years and months are not all of equal duration. More precise units are ‘fortnight’ which is worth 14 days, ‘week’ worth 7 days, ‘day’ worth 24 hours, ‘hour’ worth 60 minutes, ‘minute’ or ‘min’ worth 60 seconds, and ‘second’ or ‘sec’ worth one second. An ‘s’ suffix on these units is accepted and ignored.
Consequently (emphasis mine)
The fuzz in units can cause problems with relative items. For example, ‘2003-07-31 -1 month’ might evaluate to 2003-07-01, because 2003-06-31 is an invalid date. To determine the previous month more reliably, you can ask for the month before the 15th of the current month. For example:
$ date -R Thu, 31 Jul 2003 13:02:39 -0700 $ date --date='-1 month' +'Last month was %B?' Last month was July? $ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!' Last month was June!
The above could be expressed in PHP as
echo date('M', strtotime(date('Y-m-') . '15 -1 month'));
Also see the commments below http://bugs.php.net/bug.php?id=22486
It might be related to bug #44073
You could try with something like this :
echo date("M", strtotime("-3 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-2 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-1 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", time()) . "\n";
(Solution found in the comments section of strtotime ; direct link)
And the output :
Apr
May
Jun
Jul
Kind of "cheating" with the date format and month's name and all that...
a simple way could be to write it like this
echo date("M", strtotime("this year +3 months"));
or
echo date("M", strtotime("this month -3 months"));
depends what your using it for..
Gorden correctly identified the issue, but I wanted to give another solution that was helpful and not as technical. Just use "first day of" or "last day of" in your strtotime. Ex, these following examples overcome the issue on a 31st of a month:
// Today is May 31st
//All the following return 2012-04-30
echo date('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d');
// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month"));
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');
From PHP 5.3 (Ref: https://bugs.php.net/bug.php?id=44073) and higher you can do:
"first day of +1 month
" or "first day of next month
" or even "last day of next month
"
Example:
$date = '2015-12-31';
echo date("Y-m-d", strtotime($date ."first day of previous month"));
Will produce: 2015-11-01
This does not calculate days on +30 days time basis.
Try this instead of strtotime
:
mktime(0, (date("n") - 3 + 12) % 12, 1)
The idea is to take the current month number (date("n")
), substract the number of months from it you want (here -3
), add 12 to it and then get modulo 12.