Bug #71255 [Nab]: Error in strtotime last day of month

From: 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

« previous php.bugs (#198340) next »