Bug #80748 [Com]: DateInterval wrongly counts DateTime->diff days

From: Date: Tue, 16 Feb 2021 17:14:55 +0000
Subject: Bug #80748 [Com]: DateInterval wrongly counts DateTime->diff days
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-232209@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80748&edit=1 ID: 80748 Comment by: palansher at outlook dot com Reported by: palansher at outlook dot com Summary: DateInterval wrongly counts DateTime->diff days Status: Not a bug Type: Bug Package: Date/time related Operating System: ubuntu 18.04 PHP Version: Irrelevant Block user comment: N Private report: N New Comment: @requinix@php.net Thank you for a detailed explanation. The only thing I cannot understand is: where and how applicable dt->diff is? For example (in my case) I need only count the time difference (in whole seconds, days, weeks) independent from geography. in one city, during a 100-200 years period. Why a time zone affects these calculations at all? It is the same number of seconds for a certain year in a certain place. It is a very important and interesting question. Maybe you would so kind and advise me on a PHP tool to do this? My final goal is to design a countable week numbers system that is independent of geography. Like countable years. For example week number 1,2 ..53245. It will allow me to get the "minus three weeks" number (i.e.) from the current week just deducting =53245-3 even across the year border. The very frst week can be selected arbitrarily, i.e 1st Jan 1900 (Monday) or 1st Jan 1990 (Monday) . ISO weeks system (1-52(53)) is not suitable for that because in the case of ISO "week number 1" deducting "1" in PHP code we will get "0" but not the correct result: 52(53)'th week of the previous year. Maybe the Unix timestamps will give precise accuracy as the tool for whole weeks calculations? Thank you for your time! Previous Comments: ------------------------------------------------------------------------ [2021-02-15 23:14:07] requinix@php.net > it seems that the reason can be the "leap seconds" 1. There have been 37 leap seconds. I don't see how that can turn into 43 seconds. 2. The first leap second was in 1972. If you diff 1900 to 1970 then the difference still occurs with 25604/25605 days. It is not leap seconds. > in the last code example I set UTC timezone, not Moscow. Actually no. In your code where you use setTimezone, what you do is create a DateTime *according to the default timezone* and then modify the date to use the new timezone. If you want PHP to parse a date string according to a certain timezone then you have to specify that timezone at the time of parsing: with createFromFormat. https://3v4l.org/mWIjk Note that 3v4l's default timezone is Europe/Amsterdam, which used unusual UTC offsets through the 1930s. (Of course UTC didn't actually exist until the 1960s, so accusing Amsterdam of doing something weird according to a standard that hadn't been developed yet would be unfair.) ------------------------------------------------------------------------ [2021-02-15 13:21:12] palansher at outlook dot com @requinix@php.net >Before 1917, Moscow was GMT+02:30:17. Those 17 seconds account for the odd >behavior >around:43 seconds when you use diffs between <1917 and >1917. Thank you! But I doubt it, because: 1) in the last code example I set UTC timezone, not Moscow. 2) How timezone affects the number of seconds in a year? Such a number is always the same in any timezone, depending on the particular year of course... 3) it seems that the reason can be the "leap seconds" https://en.wikipedia.org/wiki/Leap_second. And DT->diff doesn't pay attention to it. ------------------------------------------------------------------------ [2021-02-14 21:28:36] requinix@php.net Before 1917, Moscow was GMT+02:30:17. Those 17 seconds account for the odd behavior around :43 seconds when you use diffs between <1917 and >1917. ------------------------------------------------------------------------ [2021-02-14 17:17:36] palansher at outlook dot com Found another incorrect behaviour: $beforDate=DateTime::createFromFormat('Y-m-d G:i:s', '1900-01-01 00:00:00'); $beforDate->setTimezone(new DateTimeZone('UTC')); $afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '2021-02-08 00:00:00'); $afterDate->setTimezone(new DateTimeZone('UTC')); $dtInterval = $beforDate->diff($afterDate); $daysPassed = $dtInterval->days; echo "1. days passed: $daysPassed" . PHP_EOL; $afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '2021-02-08 00:50:00'); $afterDate->setTimezone(new DateTimeZone('UTC')); $dtInterval = $beforDate->diff($afterDate); $daysPassed = $dtInterval->days; echo "1. days passed if 50 minutes added to target date: $daysPassed" . PHP_EOL; Have output: days passed: 44232 days passed if 50 minutes added to target date: 44233 https://3v4l.org/49Dv0 ------------------------------------------------------------------------ [2021-02-14 14:50:15] palansher at outlook dot com requinix@php.net, you are right. The date_default_timezone_set('Europe/Moscow'); was set. But!! a year has the same number of days in any timezone. How timezone can affect the total days number? ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=80748 -- Edit this bug report at https://bugs.php.net/bug.php?id=80748&edit=1

« previous php.bugs (#232209) next »