Ошибка перехода на летнее время Windows 7?


Я пытаюсь точно определить, когда переход на летнее время происходит в скрипте Perl, используя функцию Perl localtime и печатая часовой пояс с помощью strftime.

Странно то, что это, кажется, работает нормально для этого года и других более поздних лет, но если я попытаюсь вернуться к 2000 году, например, Perl, кажется, думает, что переход происходит в неправильный день!

По данным Google, переход на летнее время начался 2 апреля в этом году 2000:

Введите описание изображения здесь

...но по какой-то причине приведенный ниже код Perl, похоже, не согласен:

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 - %Zn", 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 - %Zn", localtime($epoch);

Вывод:

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

Почему Perl считает, что летнее время в 2000 году началось 12 марта, когда это явно неверно?


Правка:

После прочтения комментариев ниже кажется, что это может быть проблема с операционной системой, а не Perl. Похоже, это может быть ошибка в Windows 7.

1 8

1 ответ:

Я не знаю специфики внутренних компонентов Perl (и мне не хочется рыться в исходном коде), но такие ошибки обычно случаются в Windows при использовании FileTimeToLocalFileTime и еще LocalFileTimeToFileTime функции Win32. Эти функции не учитывают историю часовых поясов, а только текущие правила . Документация объясняет, что делать вместо этого:

Чтобы учесть летнее время при преобразовании времени файла в местное время, используйте следующее последовательность функций вместо использования FileTimeToLocalFileTime:

  1. FileTimeToSystemTime
  2. SystemTimeToTzSpecificLocalTime
  3. SystemTimeToFileTime
Аналогичную последовательность следует выполнить для обратной функции, используя TzSpecificLocalTimeToSystemTime для среднего шага.

Вполне вероятно, что версия Perl, которую вы запускаете, вызывает эти функции как часть реализации Win32 функций localtime и timelocal. Основываясь на комментариях в вопросе, что некоторые не смогли воспроизвести ваши результаты, я бы предположил, что новые версии Perl, вероятно, были исправлены, как описано выше. Если нет, то должны быть. (Я уверен, что кто-то более знакомый с Perl internals мог бы указать на конкретный код и отчет об ошибке.)