php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77571 DateTime's diff DateInterval incorrect in timezones from UTC+01:00 to UTC+12:00
Submitted: 2019-02-05 15:26 UTC Modified: 2021-04-06 19:55 UTC
Votes:5
Avg. Score:4.0 ± 0.9
Reproduced:4 of 4 (100.0%)
Same Version:3 (75.0%)
Same OS:2 (50.0%)
From: techouse at gmail dot com Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 7.3.1, 7.2.10 OS: macOS 10.14.3, Ubuntu 18.04
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: techouse at gmail dot com
New email:
PHP Version: OS:

 

 [2019-02-05 15:26 UTC] techouse at gmail dot com
Description:
------------
Yesterday I observed a weird DateInterval bug where adding 5 weeks would always equal 35 days but the difference in months and days would not be correct.

After some digging I figured out it was related to timezones and only affected timezones ranging from Europe/London eastward all the way to Pacific/Auckland, however as soon as I used Pacific/Honolulu the issue was gone.

Test findings

All the tests in tests/Timezones/America and tests/Timezones/Atlantic pass. Another weird thing is that Europe/London passes all tests where it does not adhere to daylight savings time (UTC+01:00).

From this I draw a conclusion that all timezones that are greater than UTC+00:00 fail because of this additional time.

All the tests and findings can be found in my GitHub repo https://github.com/techouse/php-date-interval-timezone-bug

Test script:
---------------
https://github.com/techouse/php-date-interval-timezone-bug

Expected result:
----------------
A correct DateInterval.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-02-06 08:20 UTC] techouse at gmail dot com
-Summary: DateInterval timezone bug +Summary: DateInterval reports incorrect interval when when a UTC+01:00 or greater is used -PHP Version: 7.3.1 +PHP Version: 7.3.1, 7.2.10
 [2019-02-06 08:20 UTC] techouse at gmail dot com
Updated the summary to be more descriptive and added another tested PHP version.
 [2019-02-06 08:22 UTC] techouse at gmail dot com
-Summary: DateInterval reports incorrect interval when when a UTC+01:00 or greater is used +Summary: DateInterval has incorrect interval using timezones from UTC+01:00 to UTC+12:00
 [2019-02-06 08:22 UTC] techouse at gmail dot com
Better summary
 [2019-02-06 08:55 UTC] techouse at gmail dot com
Might be related to https://bugs.php.net/bug.php?id=52480
 [2019-02-07 01:19 UTC] a at b dot c dot de
May also be related to bug #76374
 [2019-02-07 08:44 UTC] techouse at gmail dot com
I simply copied this test https://github.com/php/php-src/blob/master/ext/date/tests/DateInterval_format.phpt and changed the timezone from UTC to Europe/Paris and the test fails.


--TEST--
DateInterval::format() with timezone, except %a
--DESCRIPTION--
%a is covered in a separate test.
Don't want an XFAIL here to cause confusion if a real bug comes up.
--CREDITS--
Daniel Convissor <danielc@php.net>
# TestFest 2010 BKTK
--SKIPIF--
<?php if (!method_exists('DateInterval', 'format')) die("skip: method doesn't exist"); ?>
--FILE--
<?php
//date_default_timezone_set('UTC');
date_default_timezone_set('Europe/Paris');

$date1 = new DateTime('2000-01-01 00:00:00');
$date2 = new DateTime('2001-03-04 04:05:06');

$interval = $date1->diff($date2);

echo $interval->format('Y=%Y') . "\n";
echo $interval->format('M=%M') . "\n";
echo $interval->format('D=%D') . "\n";
echo $interval->format('H=%H') . "\n";
echo $interval->format('I=%I') . "\n";
echo $interval->format('S=%S') . "\n";
echo $interval->format('R=%R') . "\n";

echo $interval->format('y=%y') . "\n";
echo $interval->format('m=%m') . "\n";
echo $interval->format('d=%d') . "\n";
echo $interval->format('h=%h') . "\n";
echo $interval->format('i=%i') . "\n";
echo $interval->format('s=%s') . "\n";
echo $interval->format('r=%r') . "\n";

echo "\n";

$interval = $date2->diff($date1);

echo $interval->format('inverted R=%R') . "\n";
echo $interval->format('inverted r=%r') . "\n";

echo "\n";

echo $interval->format('%=%%') . "\n";

// Invalid valid format character does not raise warnings.
echo $interval->format('x=%x') . "\n";

?>
--EXPECT--
Y=01
M=02
D=03
H=04
I=05
S=06
R=+
y=1
m=2
d=3
h=4
i=5
s=6
r=

inverted R=-
inverted r=-

%=%
x=%x
 [2019-02-12 14:56 UTC] techouse at gmail dot com
-Summary: DateInterval has incorrect interval using timezones from UTC+01:00 to UTC+12:00 +Summary: DateTime's diff DateInterval incorrect in timezones from UTC+01:00 to UTC+12:00
 [2019-02-12 14:56 UTC] techouse at gmail dot com
Changed the title to have more meaning
 [2019-02-12 14:57 UTC] techouse at gmail dot com
My work colleague found out that this feature worked correctly in PHP 5.3.0, 5.3.1 and 5.3.2, however in 5.3.3 we can already observe this bug in action. Check for yourself https://3v4l.org/cupQV
 [2019-02-12 18:40 UTC] cmb@php.net
It seems to me that boils down to the question: “how many days
does a month have?”  Answer: it depends.  For instance, May has 31
days, so 31 days + 4 days = 35 days.  Correct.

If you revert the ::diff()[1], you see that April has 30 days, so
30 days + 5 days = 35 days.  Correct again.

[1] <https://3v4l.org/gocOc>
 [2019-02-12 20:24 UTC] techouse at gmail dot com
Yes, but that makes a negative diff which is not what I want. Basically in order to get a correct date I would have to subtract a negative interval instead of adding a positive one?! How crazy of an idea is that?? 

https://3v4l.org/2MNE3
 [2021-04-06 19:55 UTC] derick@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: derick
 [2021-04-06 19:55 UTC] derick@php.net
The fix for this bug has been committed.
If you are still experiencing this bug, try to check out latest source from https://github.com/php/php-src and re-test.
Thank you for the report, and for helping us make PHP better.

Fixed for PHP 8.1.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC