Bug #80748 [Opn]: DateInterval wrongly counts DateTime->diff days
| From: | palansher at outlook dot com | Date: | Sun, 14 Feb 2021 17:17:36 +0000 |
| Subject: | Bug #80748 [Opn]: DateInterval wrongly counts DateTime->diff days | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-232158@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
User updated by: palansher at outlook dot com
Reported by: palansher at outlook dot com
Summary: DateInterval wrongly counts DateTime->diff days
Status: Open
Type: Bug
Package: Date/time related
Operating System: ubuntu 18.04
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
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
Previous Comments:
------------------------------------------------------------------------
[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?
------------------------------------------------------------------------
[2021-02-14 14:43:21] palansher at outlook dot com
Just realized:
This error appears if default timezone set, like
date_default_timezone_set('Europe/Moscow');
But timezone must not affect the result.
corrected code:
date_default_timezone_set('Europe/Moscow');
$beforDate=DateTime::createFromFormat('Y-m-d G:i:s', '1900-01-01 00:00:00');
$afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '2021-02-08 00:00:42');
$dtInterval = $beforDate->diff($afterDate);
$daysPassed = $dtInterval->days;
echo "1. days passed if target date have 42 seconds from midnight: $daysPassed" . PHP_EOL;
$afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '2021-02-08 00:00:43');
$dtInterval = $beforDate->diff($afterDate);
$daysPassed = $dtInterval->days;
echo "2. days passed if target date have 43 seconds from midnight: $daysPassed" . PHP_EOL;
result:
1. days passed if target date have 42 seconds from midnight: 44232
2. days passed if target date have 43 seconds from midnight: 44233
------------------------------------------------------------------------
[2021-02-13 20:49:52] requinix@php.net
Google thinks the answer is 44202, and that's what I get on 3v4l for both $afterDates.
https://3v4l.org/QkOl8
Are you sure the timezone doesn't matter? Is your timezone database up to date?
------------------------------------------------------------------------
[2021-02-13 20:45:25] palansher at outlook dot com
Description:
------------
DateTime->diff returns different days, depending on how many seconds passed from midnight on a
target date.
This behaviour is independent of timezone settings.
Tested on PHP 7.2-7.4
The bug doesn't appear if you use short period:
<?php
$beforDate=DateTime::createFromFormat('Y-m-d G:i:s', '1900-01-01 00:00:00');
$afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '1900-01-08 00:00:43');
$dtInterval = $beforDate->diff($afterDate);
$daysPassed = $dtInterval->days;
echo "days passed if target date have 42 seconds from midnight: $daysPassed" . PHP_EOL;
$afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '1900-01-08 00:00:43');
$dtInterval = $beforDate->diff($afterDate);
$daysPassed = $dtInterval->days;
echo "days passed if target date have 43 seconds from midnight: $daysPassed" . PHP_EOL;
Test script:
---------------
<?php
$beforDate=DateTime::createFromFormat('Y-m-d G:i:s', '1900-01-01 00:00:00');
$afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '2021-01-08 00:00:42');
$dtInterval = $beforDate->diff($afterDate);
$daysPassed = $dtInterval->days;
echo "days passed if target date have 42 seconds from midnight: $daysPassed" . PHP_EOL;
$afterDate=DateTime::createFromFormat('Y-m-d G:i:s', '2021-01-08 00:00:43');
$dtInterval = $beforDate->diff($afterDate);
$daysPassed = $dtInterval->days;
echo "days passed if target date have 43 seconds from midnight: $daysPassed" . PHP_EOL;
Expected result:
----------------
days passed: 44201
Actual result:
--------------
days passed: 44202
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80748&edit=1