Bug #63953 [Com]: DateTime::diff produces a wrong DateInterval on DST change
| From: | alvaro at demogracia dot com | Date: | Wed, 18 Feb 2015 08:14:16 +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-190781@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: alvaro at demogracia 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:
This looks already fixed in PHP/5.6.0 (2014-08-28) and backport versions released on 2014-09-01:
PHP/5.4.24 and PHP/5.5.8
http://3v4l.org/MVWMG
Previous Comments:
------------------------------------------------------------------------
[2015-02-17 22:29:35] dev dot anubis at gmail dot com
Duplicate of #63442
------------------------------------------------------------------------
[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
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=63953
--
Edit this bug report at https://bugs.php.net/bug.php?id=63953&edit=1