Windows 7 夏令时错误?
Windows 7 daylight savings bug?
我正在尝试使用 Perl 的 localtime
函数准确确定 Perl 脚本中夏令时转换发生的时间,并使用 strftime
.
打印时区
奇怪的是,这似乎适用于今年和其他最近几年,但如果我尝试回到 2000 年,例如,Perl 似乎认为转换发生在错误的日子!
根据Google,夏令时从 2000 年的 4 月 2 日开始:
...但出于某种原因,下面的 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 - %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);
输出:
03/12/2000 01:59:59 - Eastern Standard Time
03/12/2000 03:00:00 - Eastern Daylight Time
为什么 Perl 认为 2000 年的夏令时从 3 月 12 日开始,而这显然是不正确的?
编辑:
阅读下面的评论后,看起来这可能是操作系统的问题,而不是 Perl 的问题。看起来这可能是 Windows 7.
中的错误
我不知道 Perl 内部的细节(我也不想搜索源代码),但是在使用 FileTimeToLocalFileTime
and LocalFileTimeToFileTime
Win32 时,这样的错误通常发生在 Windows 上职能。这些函数不考虑时区历史,只考虑 current 规则。该文档解释了该怎么做:
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
:
- FileTimeToSystemTime
- SystemTimeToTzSpecificLocalTime
- SystemTimeToFileTime
应该对反函数执行类似的序列,中间步骤使用 TzSpecificLocalTimeToSystemTime
。
很可能您使用的 Perl 版本 运行 调用这些函数作为 localtime
和 timelocal
函数的 Win32 实现的一部分。根据问题中的评论,有些人无法重现您的结果,我猜测较新版本的 Perl 可能已经如上所述进行了修补。如果不是,他们应该是。 (我相信更熟悉 Perl 内部结构的人可以指出具体的代码和错误报告。)
我正在尝试使用 Perl 的 localtime
函数准确确定 Perl 脚本中夏令时转换发生的时间,并使用 strftime
.
奇怪的是,这似乎适用于今年和其他最近几年,但如果我尝试回到 2000 年,例如,Perl 似乎认为转换发生在错误的日子!
根据Google,夏令时从 2000 年的 4 月 2 日开始:
...但出于某种原因,下面的 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 - %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);
输出:
03/12/2000 01:59:59 - Eastern Standard Time
03/12/2000 03:00:00 - Eastern Daylight Time
为什么 Perl 认为 2000 年的夏令时从 3 月 12 日开始,而这显然是不正确的?
编辑:
阅读下面的评论后,看起来这可能是操作系统的问题,而不是 Perl 的问题。看起来这可能是 Windows 7.
中的错误我不知道 Perl 内部的细节(我也不想搜索源代码),但是在使用 FileTimeToLocalFileTime
and LocalFileTimeToFileTime
Win32 时,这样的错误通常发生在 Windows 上职能。这些函数不考虑时区历史,只考虑 current 规则。该文档解释了该怎么做:
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
:
- FileTimeToSystemTime
- SystemTimeToTzSpecificLocalTime
- SystemTimeToFileTime
应该对反函数执行类似的序列,中间步骤使用 TzSpecificLocalTimeToSystemTime
。
很可能您使用的 Perl 版本 运行 调用这些函数作为 localtime
和 timelocal
函数的 Win32 实现的一部分。根据问题中的评论,有些人无法重现您的结果,我猜测较新版本的 Perl 可能已经如上所述进行了修补。如果不是,他们应该是。 (我相信更熟悉 Perl 内部结构的人可以指出具体的代码和错误报告。)