Bug #63953 [Com]: DateTime::diff produces a wrong DateInterval on DST change

From: Date: Tue, 17 Feb 2015 22:29:37 +0000
Subject: Bug #63953 [Com]: DateTime::diff produces a wrong DateInterval on DST change
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-190756@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=63953&edit=1 ID: 63953 Comment by: dev dot anubis at gmail dot com Reported by: gianluca dot pinna at allbus dot com Summary: DateTime::diff produces a wrong DateInterval on DST change Status: Open Type: Bug Package: Date/time related Operating System: Linux 64 PHP Version: 5.3.20 Block user comment: N Private report: N New Comment: Duplicate of #63442 Previous Comments: ------------------------------------------------------------------------ [2014-01-22 14:13:10] perrier dot p at gmail dot com The easy way to see the difference : http://3v4l.org/ab0Hm#v5424 The code <?php $debut = mktime(0, 0, 0, 10, 27, 2013); $fin = mktime(23, 59, 59, 11, 10, 2013); $d1 = new DateTime('now',new DateTimeZone('Europe/Paris')); $d2 = new DateTime('now',new DateTimeZone('Europe/Paris')); $d1->setTimestamp($debut); $d2->setTimestamp($fin); $diff = $d1->diff($d2); print_r($diff); ------------------------------------------------------------------------ [2013-11-06 17:30:09] alvaro at demogracia dot com Yet another test script: <?php $zone = new DateTimeZone('Europe/Madrid'); $start = new DateTime('2013-03-31 1:59:00 ', $zone); $end = new DateTime('2013-03-31 3:00:00', $zone); $difference = $start->diff($end); echo $difference->format('%H:%I:%S') . PHP_EOL; $start->setTimeZone(new DateTimeZone('UTC')); $end->setTimeZone(new DateTimeZone('UTC')); $difference = $start->diff($end); echo $difference->format('%H:%I:%S') . PHP_EOL; ?> Expected output: 00:01:00 00:01:00 Actual output: 01:01:00 00:01:00 ------------------------------------------------------------------------ [2013-06-16 19:23:01] chris at modernmedia dot co I can more or less confirm that DateInterval has Daylight Savings changes backward, at least for my 2014 test cases. In the springtime in the US we spring forward at 2am on a Sunday morning. 2am and 3am are the same exact time, and share the same exact timestamp. At 3am, 2 actual hours have elapsed since midnight. In the fall we fall backward on a Sunday at 2am. In this case, at 3am 4 actual hours have elapsed since midnight. My code shows that DateTime and DateTimezone handle DST changes correctly -- its DateInterval that is having the problem. Here's my test code: <?php /** Daylight Saving Time (United States) 2014 begins at 2:00 AM on Sunday, March 9 and ends at 2:00 AM on Sunday, November 2 */ $tz = new DateTimeZone( 'America/New_York'); $d1 = new DateTime('2014-03-09 00:00:00', $tz); echo PHP_EOL; echo 'Springing forward at 2am on Sunday, March 9, 2014...' . PHP_EOL; for ($n = 0; $n < 7; $n++){ $d2 = new DateTime(sprintf('2014-03-09 %s:00:00', $n), $tz); $ts_diff = ($d2->getTimestamp() - $d1->getTimestamp())/(60 * 60); $int = $d2->diff($d1); echo 'Comparing ' . $d2->format('g a') . ' to ' . $d1->format('g a') . PHP_EOL; echo 'Timestamp diff: ' . $ts_diff . PHP_EOL; echo 'Interval diff: ' . $int->h . PHP_EOL; } echo PHP_EOL; $d1 = new DateTime('2014-11-02 00:00:00', $tz); echo 'Falling backward at 2am on Sunday, November 2, 2014...' . PHP_EOL; for ($n = 0; $n < 7; $n++){ $d2 = new DateTime(sprintf('2014-11-02 %s:00:00', $n), $tz); $ts_diff = ($d2->getTimestamp() - $d1->getTimestamp())/(60 * 60); $int = $d2->diff($d1); echo 'Comparing ' . $d2->format('g a') . ' to ' . $d1->format('g a') . PHP_EOL; echo 'Timestamp diff: ' . $ts_diff . PHP_EOL; echo 'Interval diff: ' . $int->h . PHP_EOL; } phpinfo(INFO_GENERAL); ?> Output ======== Springing forward at 2am on Sunday, March 9, 2014... Comparing 12 am to 12 am Timestamp diff: 0 Interval diff: 0 Comparing 1 am to 12 am Timestamp diff: 1 Interval diff: 1 Comparing 2 am to 12 am Timestamp diff: 2 Interval diff: 3 Comparing 3 am to 12 am Timestamp diff: 2 Interval diff: 3 Comparing 4 am to 12 am Timestamp diff: 3 Interval diff: 4 Comparing 5 am to 12 am Timestamp diff: 4 Interval diff: 5 Comparing 6 am to 12 am Timestamp diff: 5 Interval diff: 6 Falling backward at 2am on Sunday, November 2, 2014... Comparing 12 am to 12 am Timestamp diff: 0 Interval diff: 0 Comparing 1 am to 12 am Timestamp diff: 1 Interval diff: 1 Comparing 2 am to 12 am Timestamp diff: 3 Interval diff: 2 Comparing 3 am to 12 am Timestamp diff: 4 Interval diff: 3 Comparing 4 am to 12 am Timestamp diff: 5 Interval diff: 4 Comparing 5 am to 12 am Timestamp diff: 6 Interval diff: 5 Comparing 6 am to 12 am Timestamp diff: 7 Interval diff: 6 phpinfo() PHP Version => 5.4.9 System => Darwin Christophers-MacBook-Air.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 Build Date => Dec 11 2012 12:36:33 ------------------------------------------------------------------------ [2013-02-05 17:42:11] kaido at tradenet dot ee test script: $d1 = new DateTime('2012-05-31'); $d2 = new DateTime('2013-03-02'); $diff1 = $d1->diff ($d2); $diff2 = $d2->diff ($d1); echo "case 1: ".$diff1->m." months, case 2: ".$diff2->m." months"; expected result: both $diff1->m and $diff2->m are 9 ------------------------------------------------------------------------ [2013-01-09 16:45:28] gianluca dot pinna at allbus dot com Description: ------------ I have two dates, the second date is after a DST change. I tried to get a diff between the two dates. Computing the difference between the timestamps I get the correct result (33 hours). Using DateTime->diff() I get 34 hours. Is this expected? Test script: --------------- <?php $originDate = new DateTime('2013-03-30 00:00:00', new DateTimeZone('Europe/Rome')); $destinationDate = new DateTime('2013-03-31 10:00:00', new DateTimeZone('Europe/Rome')); $diff = $destinationDate->getTimestamp() - $originDate->getTimestamp(); $dateinterval = $originDate->diff($destinationDate); var_dump($diff/3600); var_dump($dateinterval->d*24 + $dateinterval->h); // int(33) // int(34) Expected result: ---------------- I would expect to always get 33 hours. ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=63953&edit=1

« previous php.bugs (#190756) next »