Bug #80696 [Nab]: Subtracting an interval of 1 month 1 day subtracts one more day

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

« previous php.bugs (#231883) next »