Bug #75685 [Opn->Nab]: DatePeriod returns incorrect iterator count when DST ends
| From: | derick@php.net | Date: | Tue, 06 Apr 2021 18:22:00 +0000 |
| Subject: | Bug #75685 [Opn->Nab]: DatePeriod returns incorrect iterator count when DST ends | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-233235@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75685&edit=1
ID: 75685
Updated by: derick@php.net
Reported by: markus dot weiland at mapudo dot com
Summary: DatePeriod returns incorrect iterator count when DST
ends
-Status: Open
+Status: Not a bug
Type: Bug
Package: Date/time related
Operating System: Linux
PHP Version: 7.1.12
Block user comment: N
Private report: N
New Comment:
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
As CMB already alluded too, "2017-10-30T02:00" is CET, so the result is expected:
php -r "echo (new DateTime('2017-10-29T02:00:00', new
DateTimeZone('Europe/Berlin')))->format(\DateTime::ISO8601);"
2017-10-29T02:00:00+0100
Previous Comments:
------------------------------------------------------------------------
[2020-11-03 11:49:43] cmb@php.net
Well, I think the problem is whether
new DateTime('2017-10-29T02:00:00', new DateTimeZone('Europe/Berlin'))
is CET or CEST.
------------------------------------------------------------------------
[2017-12-14 10:00:10] markus dot weiland at mapudo dot com
Description:
------------
DatePeriod allows calculating the number of occurrences of a given interval in the specified period
(from start to end).
For example, we can obtain the number of hours for each calendar day in the year with
iterator_count() and print out the number if it is not 24.
Using the example code, we can determine that one hour is missing in 2017 when using this method of
calculation and a timezone other than UTC.
Test script:
---------------
$interval = new \DateInterval('PT1H'); // plus time one hour
$i = 0;
while ($i < 366) {
$start = new \DateTime('2017-01-01 00:00:00', new
\DateTimeZone('Europe/Berlin'));
$start->add(new \DateInterval('P'.$i.'D'));
$end = new \DateTime('2017-01-02 00:00:00', new
\DateTimeZone('Europe/Berlin'));
$end->add(new \DateInterval('P'.$i.'D'));
$period = new \DatePeriod($start, $interval, $end);
$diff = iterator_count($period);
if ($diff != 24) {
echo sprintf('%s, %d', $start->format(\DateTime::ISO8601), $diff);
}
$i++;
}
Expected result:
----------------
We expect to have two values printed to console (i.e. there is one iterator with 23 counts and one
with 25 counts):
2017-03-26T00:00:00+0100, 23
2017-10-29T00:00:00+0100, 25
The first, when daylight savings time (DST) starts, the second when DST ends.
This means that the total number of hours in 2017 is 8760 which is equivalent to 365 days of 24
hours.
Actual result:
--------------
Only one value is printed to console:
2017-03-26T00:00:00+0100, 23
This means that the total number of hours in 2017 is 8759 which is _not_ equivalent to 365 days of
24 hours. In other words, one hour is missing, even though 2017 is a "regular" year
without leap days, leap seconds, etc..
In contrast, when using UTC as timezone in the example code, the year has 8760 hours as
expected.
Double-checking with DateTimeZone::getTransitions() for Europe/Berlin
shows that a transition on 2017-10-29 is correctly defined.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75685&edit=1