Bug #80664 [Opn]: DateTime objects behave incorrectly around DST transition
Edit report at https://bugs.php.net/bug.php?id=80664&edit=1
ID: 80664
User updated by: AaronB at landproDATA dot com
Reported by: AaronB at landproDATA dot com
-Summary: DateTime::add() behaves incorrectly at DST
transition
+Summary: DateTime objects behave incorrectly around DST
transition
Status: Open
Type: Bug
Package: Date/time related
Operating System: Irrelevant
PHP Version: 7.3.26
Block user comment: N
Private report: N
New Comment:
After more testing, I discovered that, at these problematic transition points, changing the
DateTimeZone of a DateTime object can actually change the underlying Unix timestamp -- which, as far
as I know, should never happen. So, this bug report can also be regarded as reporting a bug in the
DateTime::setTimezone() function.
Here is an example that illustrates the problem:
$dt = new DateTime('@1604219400');
$dt->setTimezone(new DateTimeZone('UTC'));
echo "{$dt->format('Y-m-d H:i:s T')} | {$dt->getTimestamp()}\r\n";
$dt->setTimezone(new DateTimeZone('America/Boise'));
echo "{$dt->format('Y-m-d H:i:s T')} | {$dt->getTimestamp()}\r\n";
Expected result:
----------------
2020-11-01 08:30:00 UTC | 1604219400
2020-11-01 01:30:00 MST | 1604219400
Actual result:
--------------
2020-11-01 08:30:00 UTC | 1604219400
2020-11-01 01:30:00 MST | 1604215800
Previous Comments:
------------------------------------------------------------------------
[2021-01-24 21:53:45] AaronB at landproDATA dot com
Description:
------------
DateTime::add() behaves incorrectly when adding times to a DateTime representing a point during the
hour that is repeated during a transition from daylight savings time to standard time. This problem
seems to arise only in cases where the associated DateTimeZone has been defined using a geographical
label like 'America/Boise'.
One thing that is especially surprising in these cases is that using DateTime::add() to add an hour
to a time can cause the description of the timezone that is reported by the 'T' format
option to change in such a way that the operation appears to have succeed as intended while the call
to DateTime::add() actually leaves the underlying Unix timestamp entirely unchanged. What this means
is that there is a bug in DateTime::format(), as well as in DateTime::add().
I have verified that this problem occurs in PHP 7.3.21 and PHP 7.4.0.
Test script:
---------------
$dt = new DateTime('@1604215800');
$dt->setTimezone(new DateTimeZone('America/Boise'));
echo "{$dt->format('Y-m-d H:i:s T')} | {$dt->getTimestamp()}\r\n";
$dt->add(new DateInterval('PT1H'));
echo "{$dt->format('Y-m-d H:i:s T')} | {$dt->getTimestamp()}\r\n";
$dt->add(new DateInterval('PT1H'));
echo "{$dt->format('Y-m-d H:i:s T')} | {$dt->getTimestamp()}\r\n";
$dt->add(new DateInterval('PT1M'));
echo "{$dt->format('Y-m-d H:i:s T')} | {$dt->getTimestamp()}\r\n";
Expected result:
----------------
2020-11-01 01:30:00 MDT | 1604215800
2020-11-01 01:30:00 MST | 1604219400
2020-11-01 02:30:00 MST | 1604223000
2020-11-01 02:31:00 MST | 1604223060
Actual result:
--------------
2020-11-01 01:30:00 MDT | 1604215800
2020-11-01 01:30:00 MST | 1604215800
2020-11-01 01:30:00 MST | 1604215800
2020-11-01 01:31:00 MDT | 1604215860
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80664&edit=1
Thread (4 messages)