|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-01-24 21:53 UTC] 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
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 03:00:02 2025 UTC |
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