Bug #80696 [Nab]: Subtracting an interval of 1 month 1 day subtracts one more day
| From: | requinix@php.net | Date: | Tue, 02 Feb 2021 02:22:51 +0000 |
| Subject: | Bug #80696 [Nab]: Subtracting an interval of 1 month 1 day subtracts one more day | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-231883@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=80696&edit=1
ID: 80696
Updated by: requinix@php.net
Reported by: jurchiks101 at gmail dot com
Summary: Subtracting an interval of 1 month 1 day subtracts
one more day
Status: Not a bug
Type: Bug
Package: Date/time related
Operating System: Windows 10
PHP Version: 7.4.14
Block user comment: N
Private report: N
New Comment:
> It would seem to me that the solution is to flip the order depending on the operation:
There is no solution here. Not simply because "this isn't a bug" but because changing
how the diff is calculated to suit your expectations will cause issues for everyone else who thinks
the diff should be the way it is now.
Like I said: dates are hard.
I don't know what your use case here is but depending on these diffs to work a certain way
might not be the right answer.
Previous Comments:
------------------------------------------------------------------------
[2021-02-02 01:24:23] jurchiks101 at gmail dot com
Is it that PHP subtracts and adds using the same order?
It would seem to me that the solution is to flip the order depending on the operation:
2021-01-01 - P1M = 2020-12-01
2020-12-01 - P1D = 2020-11-31
reverse:
2020-11-31 + P1D = 2020-12-01
2020-12-01 + P1M = 2021-01-01
------------------------------------------------------------------------
[2021-02-02 01:05:55] requinix@php.net
What part, my brief explanation or PHP's behavior? I'll assume the former.
That's good because it gives me a chance to mention that I got it backwards.
2021-01-01 minus P1M1D is 2020-11-30. Agreed on that?
2020-11-30 plus P1M = 2020-12-30
2020-12-30 plus P1D = 2021-12-31
Compare with
2020-11-30 plus P1D = 2020-12-01
2020-12-01 plus P1M = 2021-01-01
Same starting date, same ending date, different intervals depending how you count it.
------------------------------------------------------------------------
[2021-02-02 00:58:48] jurchiks101 at gmail dot com
Well that makes no sense. Great!
------------------------------------------------------------------------
[2021-02-02 00:53:33] requinix@php.net
You calculate the diff by counting days before months. PHP calculates the diff by counting months
before days.
Dates are hard.
------------------------------------------------------------------------
[2021-02-01 23:33:09] jurchiks101 at gmail dot com
Description:
------------
When subtracting an interval that contains months and days, the number of days subtracted is
sometimes increased by an inconsistent amount.
Here's the 3v4l: https://3v4l.org/uIWq4
Test script:
---------------
$firstDayOfYear = new DateTimeImmutable('2021-01-01 00:00:00.000000');
for ($i = 1; $i <= 12; $i++) {
$intervalOneEach = new DateInterval('P' . $i . 'M1D');
echo $firstDayOfYear
->sub($intervalOneEach)
->diff($firstDayOfYear)
->format('%y years %m months %d days %h hours %i minutes %s seconds'), PHP_EOL;
}
Expected result:
----------------
0 years 1 months 1 days 0 hours 0 minutes 0 seconds
0 years 2 months 1 days 0 hours 0 minutes 0 seconds
0 years 3 months 1 days 0 hours 0 minutes 0 seconds
0 years 4 months 1 days 0 hours 0 minutes 0 seconds
0 years 5 months 1 days 0 hours 0 minutes 0 seconds
0 years 6 months 1 days 0 hours 0 minutes 0 seconds
0 years 7 months 1 days 0 hours 0 minutes 0 seconds
0 years 8 months 1 days 0 hours 0 minutes 0 seconds
0 years 9 months 1 days 0 hours 0 minutes 0 seconds
0 years 10 months 1 days 0 hours 0 minutes 0 seconds
0 years 11 months 1 days 0 hours 0 minutes 0 seconds
1 years 0 months 1 days 0 hours 0 minutes 0 seconds
Actual result:
--------------
0 years 1 months 2 days 0 hours 0 minutes 0 seconds
0 years 2 months 1 days 0 hours 0 minutes 0 seconds
0 years 3 months 2 days 0 hours 0 minutes 0 seconds
0 years 4 months 1 days 0 hours 0 minutes 0 seconds
0 years 5 months 1 days 0 hours 0 minutes 0 seconds
0 years 6 months 2 days 0 hours 0 minutes 0 seconds
0 years 7 months 1 days 0 hours 0 minutes 0 seconds
0 years 8 months 2 days 0 hours 0 minutes 0 seconds
0 years 9 months 1 days 0 hours 0 minutes 0 seconds
0 years 10 months 3 days 0 hours 0 minutes 0 seconds
0 years 11 months 1 days 0 hours 0 minutes 0 seconds
1 years 0 months 1 days 0 hours 0 minutes 0 seconds
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80696&edit=1