Edit report at https://bugs.php.net/bug.php?id=68981&edit=1
ID: 68981
Updated by: derick@php.net
Reported by: teo8976 at gmail dot com
Summary: negative relative month values in strtime() give
nonsense results
-Status: Open
+Status: Not a bug
Type: Bug
Package: Date/time related
Operating System: linux
PHP Version: 5.6.5
Block user comment: N
Private report: N
New Comment:
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
Previous Comments:
------------------------------------------------------------------------
[2018-02-27 01:20:24] calebpitman at gmail dot com
The documentation may address this, but ultimately this makes no sense:
+1 month from 01/31/2018 = 03/03/2018
+1 month from 02/01/2018 = 03/01/2018
The difference of a month should change the actual value of the month. The unit of measurement
isn't days, regardless of how many days are in the month. The unit is months. Because a month
has a different amount of days shouldn't affect the outcome. December -1 month is logically
November. If it's the last day of the month, it would logically fall on the last day of the
month in November.
+1 month from 1/31/2018 would logically be 2/28/2018 or 2/29/2018, because it's a unit of
months.
The very last second of 1/31/2018 is 1517443199.
+1 month from 1517443199 should be the very last second of February, because the unit is months.
------------------------------------------------------------------------
[2015-02-03 20:37:20] teo8976 at gmail dot com
Indeed I think you are right that the current behavior makes sense,
but documentation then is definitely wrong and needs to be corrected.
See https://bugs.php.net/bug.php?id=60353#1422995592
------------------------------------------------------------------------
[2015-02-03 20:18:52] teo8976 at gmail dot com
Well, then the documentation doesn't accurately describe the behavior.
From http://php.net/manual/en/datetime.formats.relative.php
"Note:
Relative month values are calculated BASE ON THE LENGTH OF MONTHS THEY PASS THROUGH. An example
would be "+2 month 2011-11-30", which would produce "2012-01-30". This is due to
November being 30 days in length, and December being 31 days in length, producing a total of 61
days."
The only sensible way to extend that reasoning (the one in documentation, which is completely
different from yours) to subtractions is to assume that the number of days subtracted is the number
of days of the month to which the starting date belong, plus the number of days of the previous
month, etc.
According to that statement in documentation, relative formats with dates are not supposed to
add/subtract to the index of the month and then "wrap". They are supposed to add/subtract
the number of days that correspond to each month.
Instead, it does seem to behave the way you describe, even for positive months.
So either the documentation or the behavior needs to be fixed.
It would definitely make more sense to fix the behavior, because the one described in the
documentation is much more desirable and intuitive.
------------------------------------------------------------------------
[2015-02-03 19:04:35] requinix@php.net
You told strtotime() to subtract months from a date so it did that. But rather than error out when
it arrived at dates like November 31st or February 31st, it wrapped the date to the next month. Like
mktime() would have.
If you want the last day of each month then you have to say that.
http://3v4l.org/QSorH
------------------------------------------------------------------------
[2015-02-03 18:36:01] teo8976 at gmail dot com
Description:
------------
The way negative relative month values are handled by strtotime() is
1) undocumented
2) complete nonsense
example: strtotime("-3 months", $date)
Test script:
---------------
$end_date=mktime(23,59,59,12,31,2014);
echo date("r", $end_date)."\n";
$date=strtotime("-1 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-2 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-3 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-4 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-5 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-6 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-7 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-8 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-9 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-10 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-11 months", $end_date);
echo date("r", $date)."\n";
$date=strtotime("-12 months", $end_date);
echo date("r", $date)."\n";
Expected result:
----------------
Wed, 31 Dec 2014 23:59:59 +0100
Mon, 30 Nov 2014 23:59:59 +0100
Fri, 31 Oct 2014 23:59:59 +0100
Wed, 30 Sep 2014 23:59:59 +0200
Sun, 31 Aug 2014 23:59:59 +0200
Thu, 31 Jul 2014 23:59:59 +0200
Tue, 30 Jun 2014 23:59:59 +0200
Sat, 31 May 2014 23:59:59 +0200
Thu, 30 Apr 2014 23:59:59 +0200
Mon, 31 Mar 2014 23:59:59 +0200
Mon, 28 Feb 2014 23:59:59 +0100
Fri, 31 Jan 2014 23:59:59 +0100
Tue, 31 Dec 2013 23:59:59 +0100
Actual result:
--------------
Wed, 31 Dec 2014 23:59:59 +0100
Mon, 01 Dec 2014 23:59:59 +0100
Fri, 31 Oct 2014 23:59:59 +0100
Wed, 01 Oct 2014 23:59:59 +0200
Sun, 31 Aug 2014 23:59:59 +0200
Thu, 31 Jul 2014 23:59:59 +0200
Tue, 01 Jul 2014 23:59:59 +0200
Sat, 31 May 2014 23:59:59 +0200
Thu, 01 May 2014 23:59:59 +0200
Mon, 31 Mar 2014 23:59:59 +0200
Mon, 03 Mar 2014 23:59:59 +0100 << THIS IS PARTICULARLY HILARIOUS
Fri, 31 Jan 2014 23:59:59 +0100
Tue, 31 Dec 2013 23:59:59 +0100
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=68981&edit=1