Windows 7 daylight savings bug?
Asked Answered
F

1

8

I am trying to determine exactly when a daylight savings transition occurs in a Perl script using Perl's localtime function and printing the time zone using strftime.

The strange thing is this seems to work fine for this year and other more recent years, but if I try and go back to the year 2000 for example, Perl seems to think the transition occurs on the wrong day!

According to Google, daylight savings started on April 2nd in the year 2000:

enter image description here

...but for some reason, the Perl code below seems to disagree:

use POSIX qw(strftime);
use Time::Local;

# 03/12/2000 01:59:59
($year, $month, $day, $hour, $minute, $second) = (2000, 3, 12, 1, 59, 59);
$epoch = timelocal($second, $minute, $hour, $day, $month - 1, $year);

# Print the time
print strftime "%m/%d/%Y %H:%M:%S - %Z\n", localtime($epoch);

# 03/12/2000 02:00:00
($year, $month, $day, $hour, $minute, $second) = (2000, 3, 12, 2, 0, 0);
$epoch = timelocal($second, $minute, $hour, $day, $month - 1, $year);

# Print the time
print strftime "%m/%d/%Y %H:%M:%S - %Z\n", localtime($epoch);

Output:

03/12/2000 01:59:59 - Eastern Standard Time
03/12/2000 03:00:00 - Eastern Daylight Time

Why does Perl think that daylight savings time in the year 2000 started on March 12th when clearly this is incorrect?


EDIT:

After reading the comments below it looks like this may be an issue with the operating system and not Perl. It looks like this may be a bug in Windows 7.

Fountainhead answered 14/4, 2016 at 18:2 Comment(9)
What version of Perl are you running?Egidio
I am running Perl v5.20.1Fountainhead
I don't get the same result on my machine; I get 01:59:59 - EST and 02:00:00 - EST. Also, perl is using system (libc) functions to determine timezones and when DST begins and ends. So I suspect the problem is in your system timezone database, not in perl.Exoteric
In 2007 the US began observing DST starting on the second Sunday of March (before that it was the first Sunday of April). It looks like your system is mistakenly applying the new rules to years before they were put into effect.Exoteric
I'm not sure if this deserves to be an answer; I'll make it one if asked.Exoteric
@hobbs, Would that mean this is a bug that is part of the OS? What are these libc functions and where do they come from?Fountainhead
Just tested this on one of our Linux servers and it seems to work correctly there. Looks like this may be a bug in Windows 7.Fountainhead
I also get the correct 03/12/2000 01:59:59 - CET and 03/12/2000 02:00:00 - CET. I'm running Ubuntu 14.04 and ldd --version shows me ldd (Ubuntu EGLIBC 2.19-0ubuntu6.7) 2.19. Try ldd --version to show the libc's version. Interesting observation of yours, though.Maroney
Using the DateTime library will work on any system. It has it's own time zone DB and conversion functions.Tagalog
E
3

I don't know the specifics of the Perl internals (nor do I feel like scouring through the source code), but bugs like this usually happen on Windows when using the FileTimeToLocalFileTime and LocalFileTimeToFileTime Win32 functions. These functions don't take the history of time zones into account, only the current rules. The documentation explains what to do instead:

To account for daylight saving time when converting a file time to a local time, use the following sequence of functions in place of using FileTimeToLocalFileTime:

  1. FileTimeToSystemTime
  2. SystemTimeToTzSpecificLocalTime
  3. SystemTimeToFileTime

A similar sequence should be done for the inverse function, using TzSpecificLocalTimeToSystemTime for the middle step.

It's likely that the version of Perl you're running is calling these functions as part of the Win32 implementation of the localtime and timelocal functions. Based on the comments in the question that some couldn't reproduce your results, I'd guess that newer versions of Perl probably have been patched as described above. If not, they should be. (I'm sure someone more familiar with Perl internals could point out the specific code and bug report.)

Easygoing answered 19/4, 2016 at 22:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.