Bug #42645 [Nab]: getdate/mktime does not always add/subtract dst offset
| From: | requinix@php.net | Date: | Wed, 08 Apr 2015 22:15:18 +0000 |
| Subject: | Bug #42645 [Nab]: getdate/mktime does not always add/subtract dst offset | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-191910@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=42645&edit=1
ID: 42645
Updated by: requinix@php.net
Reported by: carstenklein at yahoo dot de
Summary: getdate/mktime does not always add/subtract dst
offset
Status: Not a bug
Type: Bug
Package: Date/time related
Operating System: Linux Ubuntu
PHP Version: 5.2.4
Block user comment: N
Private report: N
New Comment:
Reply to the invalid thing first:
>One more thing, though
>1981-03-29 02:30:00
>is a very valid date and time.
>Not so much
>1981-02-29 02:30:00
>which I believe you had in mind.
Not in the Europe/Amsterdam timezone, which is where the 3v4l code I posted is running. Their 1981
spring DST change was on 1981-03-29 and they went from 01:59:59 to 03:00:00. There was no 02:30:00
on that day. So, invalid.
And the rest:
>See the actual, it already has the timezone offset added to it.
"Already" because the code tries to use 2:30, which isn't valid (for that date), and
the most reasonable interpretation of that would be after the timezone offset change where it
becomes 3:30.
>$t = getdate( $date )
Not sure what you're trying to say with this...
getdate() seems to be behaving as it should.
http://3v4l.org/OCfb2
For the 28th and 30th there's nothing special, but for the 29th it does the same thing
demonstrated in my code where it wraps 2:30 to 3:30. Because, again, invalid time (for that date).
>which will already apply the dst offset on a rather random basis.
DST was only applied in one place: when correcting the start time given for the 3/29 date.
>Or rather not so much random as sunday is considered the first day of the week in some regions
>of the world.
Sunday being the first day or not is irrelevant to any of this: it's purely a matter of DST
changes.
Previous Comments:
------------------------------------------------------------------------
[2015-04-08 21:18:18] carstenklein at yahoo dot de
One more thing, though
1981-03-29 02:30:00
is a very valid date and time.
Not so much
1981-02-29 02:30:00
which I believe you had in mind.
------------------------------------------------------------------------
[2015-04-08 21:14:40] carstenklein at yahoo dot de
*) what is marked as FAILURE is actually correct, however,
all the other dates before also transition from non-dst to dst,
in the local configuration, i.e. CET to CEST, so these
should also have a local time reading of 03:30:30 instead
of just 02:30:30.
considering the above, overall dst behaviour of getdate() seems to be off.
and besides of that, if you feel happy with your current solution, go on with it as I have moved
pass PHP and am no longer using it.
------------------------------------------------------------------------
[2015-04-08 21:10:04] carstenklein at yahoo dot de
Or rather not so much random as sunday is considered the first day of the week in some regions of
the world.
Perhaps in getdate() there is some special cased dst adjustment logic that needs to be eliminated?
------------------------------------------------------------------------
[2015-04-08 21:05:22] carstenklein at yahoo dot de
It seems as if you are missing the actual point here.
Actual: 1981-03-29 03:30:00 + 3 days = 1981-04-01 03:30:00 <--- ERR
See the actual, it already has the timezone offset added to it. Naturally, the calculated datetime
will have it, too.
So the actual problem lies within
$t = getdate( $date )
which will already apply the dst offset on a rather random basis.
As such I would consider this a standing bug rather than a NAB.
------------------------------------------------------------------------
[2015-04-08 20:46:25] requinix@php.net
Alright. Then after almost 8 years of this bug being around, I'm going to close this as NAB.
Here's why:
The most important thing is that 1981-03-29 02:30:00 is not a valid time (in that timezone). It does
not exist. See how the code tries to use 2:30 for the start time but the actual printout says 3:30?
The most reasonable interpretation of 2:30 is "2 hours 30 minutes after midnight", but
because of daylight savings and the jump from 1:59:59 to 3:00:00, that time turns out to be 3:30 AM.
If you add whatever day interval to that then you're still going to get 3:30 AM because (1) it
didn't start at 2:30 and (2) all "+N days" does is add N to the day number, then
potentially adjust for wrapping out-of-bounds numbers and such (eg, 3/29 +3 days = 3/32, which wraps
to 4/1).
So you can't actually start with a datetime of 1981-03-29 02:MM:SS. You can, however, simulate
that by using mktime() *and adding your day interval at the same time*. As in
mktime(2, 30, 0, 3, 29 + 3, 1981) // adding the day at this point
http://3v4l.org/8ob1c
By doing that you bypass the "invalid time" problem but still make use of the "adjust
for wrapping" feature. It also more closely reflects the logical process of "take this
date and add 3 days to it" that a human would follow.
------------------------------------------------------------------------
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=42645
--
Edit this bug report at https://bugs.php.net/bug.php?id=42645&edit=1