【发布时间】:2019-06-18 09:21:35
【问题描述】:
我有系统时区为 EST 的服务器
它是用
设置的# timedatectl set-timezone EST
# timedatectl
Local time: Tue 2019-06-18 03:29:42 EST
Universal time: Tue 2019-06-18 08:29:42 UTC
RTC time: Tue 2019-06-18 08:29:42
Time zone: EST (EST, -0500)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
然后在我的 perl 代码中,我尝试检测时区并将时间转换为 UTC 由于某种原因,时区被检测为 EDT。目前(夏季)EST 是我们在 EDT 之后的一个
我的 perl 代码是
# cat test.cgi # code file is named test.cgi
#!/usr/bin/perl -w
use Date::Manip;
print "Local time: ".UnixDate("now","%Y-%m-%d %H:%M:%S %Z")."\n";
# get local system timezone
my $TZ = UnixDate("now","%Z");
# convert time to GMT
my $dtlocal = Date_ConvTZ(ParseDate(UnixDate("now","%g")),$TZ,"GMT");
# format GMT time
my $dt = UnixDate($dtlocal,"%Y-%m-%d %H:%M:%S");
print "Timezone: $TZ\n";
print "UTC time: $dt\n";
然后我执行脚本
# date
Tue Jun 18 04:17:56 EST 2019
# date -u
Tue Jun 18 09:17:58 UTC 2019
# ./test.cgi
Local time: 2019-06-18 04:18:00 EDT
Timezone: EDT
UTC time: 2019-06-18 08:18:00
Date::Manip 错误检测时区的原因是什么? 还有其他检测系统时区的好方法吗?
更新。
我刚刚发现 POSIX 可以正确检测时区。所以,问题在于 Date::Manip
use POSIX;
print strftime("%Z", localtime()), "\n";
【问题讨论】:
-
我无法很快找到 Date::Manip 决定您是在标准时间还是 DST 的确切位置,但美国在 2007 年更改了 DST 的开始/结束日期。您的 Date::Manip 是否可能已经足够老,仍然使用旧的开始/结束日期而不是当前日期?
-
我的版本是 6.54 ,根据他们的文档,它来自 2016-05-31 。 metacpan.org/changes/distribution/Date-Manip
-
我已经使用最新版本的 Date::Manip (6.77) 运行了您的代码,但我仍然看到相同的不正确行为。我建议reporting it as a bug。
-
请务必记住,EST 和 EDT 不是完全实现的时区。它们是偏移量。时区是 America/New_York(或适当的语言环境)。这就是您可以在同一时区中使用不同偏移量的冬季日期时间和夏季日期时间的方法。因此,DST 是否生效的“决定”取决于所讨论的时区和日期时间。
-
因此听起来 Date::Manip 太聪明了,并假设所有 EST 时区都是 America/New_York。
标签: perl datetime date-manipulation