Bug #71255 [Nab]: Error in strtotime last day of month
| From: | rasmus@php.net | Date: | Thu, 31 Dec 2015 23:31:46 +0000 |
| Subject: | Bug #71255 [Nab]: Error in strtotime last day of month | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-198340@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=71255&edit=1
ID: 71255
Updated by: rasmus@php.net
Reported by: ruben at solunapilates dot es
Summary: Error in strtotime last day of month
Status: Not a bug
Type: Bug
Package: Date/time related
Operating System: Ubuntu 14.04
PHP Version: 5.5.30
Block user comment: N
Private report: N
New Comment:
Of course not, 2016/02/29 - a year would be 2015/03/01. This is how UNIX date math works. You can
try the original issue from your Linux shell prompt:
% date --date='-1 month' +'Last month was %B?'
Last month was December?
Or in sqlite:
sqlite> select datetime('2015-12-31', '-1 month');
2015-12-01 00:00:00
See this for some extra background:
http://www.gnu.org/software/tar/manual/html_node/Relative-items-in-date-strings.html#SEC120
PHP is consistent with GNU tools and the many other tools using this standard approach. In the end
there is no right answer when you are subtracting a fuzzy concept such as a year or a month.
Take this, for example:
php > echo date('Y/m/d', strtotime('-1 month',
strtotime('2015/12/31')));
2015/12/01
php > echo date('Y/m/d', strtotime('-1 month',
strtotime('2015/12/30')));
2015/11/30
By your logic these should both return the same day? That doesn't make much sense. Having 31-n
== 30-n would make doing math on timestamps and comparing results really difficult if 31-n was not
greater than 30-n. UNIX chooses mathematical consistency at the timestamp level. Mapping these
timestamps to a display date is where things get interesting and you have to take this into account
when you apply fuzzy concepts like months and years to timestamps.
Previous Comments:
------------------------------------------------------------------------
[2015-12-31 20:29:03] a at b dot c dot de
By that logic, date('Y', strtotime('-1 year',
strtotime('2016-02-29'))) should return 2012 because 2015-02-29 doesn't exist.
------------------------------------------------------------------------
[2015-12-31 19:13:19] ruben at solunapilates dot es
Hi, Yes, your workaround works, but the right behaviour must be "if 31/11 doesn't exist,
show a month before" because we are trying to get "a month before" (-1 month), is
not?
------------------------------------------------------------------------
[2015-12-31 14:10:12] bwoebi@php.net
That just happens on months with more days than previous month on the last day.
December 31 - 1 month = November 31 => December 1
Better try date('F',strtotime('first day of last month')), which will give you
what you expect.
------------------------------------------------------------------------
[2015-12-31 11:56:42] ruben at solunapilates dot es
Description:
------------
In day 31 of December, the function date('F',strtotime('- 1 month')); returns
"December" instead November. Happens all months
Test script:
---------------
$today=date('F',strtotime('- 1 month'));
print($today);
Expected result:
----------------
November
Actual result:
--------------
December
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=71255&edit=1