|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2014-12-05 05:22 UTC] mfaust at usinternet dot com
Description: ------------ Unix timestamps are not respected during daylight savings transitions. When specifying a timestamp during a repeated hour, DateTime silently(incorrectly) modifies the timestamp to the previous hour. In regards to the proposed https://wiki.php.net/rfc/datetime_and_daylight_saving_time change, there are some current behaviors in regards to the "fall back" repeated hour that sorely need to be addressed. For those that understand and need proper and accurate date/time handling it is crucial that these inconsistent behaviors are eliminated. Test script: --------------- //A timestamp indicates a fixed point in time, irregardless of timezone and daylight savings, so PHP must not change it when setting it: $x = new DateTime(); $x->setTimezone(new DateTimezone('America/Chicago')); $x->setTimestamp(1446357600); echo $x->format('c') . "\n"; $x->setTimestamp(1446361200); echo $x->format('c') . "\n"; //This should have a different offset since it's outside DST echo $x->getTimestamp(); //Simpler example $x = new DateTime(); $x->setTimezone(new DateTimezone('America/Chicago')); $x->setTimestamp(1446361200); echo $x->getTimestamp(); //Returns a different timestamp. No apparent way to specify a timestamp during the repeated hour. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Nov 02 20:00:01 2025 UTC |
This is another test case showing that daylight saving time is poorly handled. <?php echo "Expected DateTime in ISO8601: 2014-10-26T02:00:00+0200 Expected DateTime in RFC850: Sunday, 26-Oct-14 02:00:00 GMT+0200 Expected Timestamp: 1414281600\n"; echo "--------------------------------------------\n"; $date = new \DateTime("2014-10-26T02:00:00+02:00"); $date->setTimeZone(new \DateTimeZone('Europe/Paris')); echo "Actual DateTime in ISO8601: ", $date->format(\DateTime::ISO8601) ,"\n"; echo "Actual DateTime in RFC850: ", $date->format(\DateTime::RFC850) ,"\n"; echo "Actual timestamp: ", $date->getTimestamp() ,"\n"; echo "--------------------------------------------\n"; echo "--------------------------------------------\n"; echo "Expected DateTime in ISO8601: 2014-10-26T03:00:00+0200 Expected DateTime in RFC850: Sunday, 26-Oct-14 03:00:00 GMT+0200 Expected timestamp: 1414285200\n"; echo "--------------------------------------------\n"; $date = new \DateTime("2014-10-26T03:00:00+02:00"); $date->setTimeZone(new \DateTimeZone('Europe/Paris')); echo "Actual DateTime in ISO8601: ", $date->format(\DateTime::ISO8601) ,"\n"; echo "Actual DateTime in RFC850: ", $date->format(\DateTime::RFC850) ,"\n"; echo "Actual timestamp: ", $date->getTimestamp() ,"\n"; ?> This scripts run on PHP 5.5.9 output : Expected DateTime in ISO8601: 2014-10-26T02:00:00+0200 Expected DateTime in RFC850: Sunday, 26-Oct-14 02:00:00 GMT+0200 Expected Timestamp: 1414281600 -------------------------------------------- Actual DateTime in ISO8601: 2014-10-26T02:00:00+0200 Actual DateTime in RFC850: Sunday, 26-Oct-14 02:00:00 CEST Actual timestamp: 1414285200 -------------------------------------------- -------------------------------------------- Expected DateTime in ISO8601: 2014-10-26T03:00:00+0200 Expected DateTime in RFC850: Sunday, 26-Oct-14 03:00:00 GMT+0200 Expected timestamp: 1414285200 -------------------------------------------- Actual DateTime in ISO8601: 2014-10-26T02:00:00+0100 Actual DateTime in RFC850: Sunday, 26-Oct-14 02:00:00 CET Actual timestamp: 1414285200 So according to PHP 'Sunday, 26-Oct-14 02:00:00 CEST' and 'Sunday, 26-Oct-14 02:00:00 CET' refer to same timestamp '1414285200' which is wrong. For 'Sunday, 26-Oct-14 02:00:00 CEST', it should show 1414281600.Still going wrong in php 7.4.3: <?php // $originalTimestamp = 1636275599; // ok $originalTimestamp = 1636275600; // wrong (- 3600 sec) // $originalTimestamp = 1636279199; // wrong (- 3600 sec) // $originalTimestamp = 1636279200; // ok $tz = new DateTimeZone('America/Los_Angeles'); // this fails in the opposite way: // $originalTimestamp = 1635638399; // ok // $originalTimestamp = 1635638400; // wrong (+ 3600 sec) // $originalTimestamp = 1635641999; // wrong (+ 3600 sec) // $originalTimestamp = 1635642000; // ok // $tz = new DateTimeZone('Europe/Amsterdam'); $dt = new DateTime('now', $tz); print_r($dt); printf("now ISO8601 format: %s\n", $dt->format(DateTimeInterface::ISO8601)); printf("now timestamp: %d\n", $dt->getTimestamp()); printf("\nsetting timestamp to %d:\n\n", $originalTimestamp); $dt->setTimestamp($originalTimestamp); $actualTimestamp = $dt->getTimestamp(); print_r($dt); printf("DateTime object's ISO8601 format: %s\n", $dt->format(DateTimeInterface::ISO8601)); printf("DateTime object's UNIX timestamp: %d\n", $actualTimestamp); printf("difference (should be 0): %d\n", $actualTimestamp - $originalTimestamp); ?> How is this bug seven years old with not even a response in sight...