我的服务器所在的系统时区为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";
答案 0 :(得分:3)
找到时区的一种方法是使用DateTime::TimeZone。与DateTime一起用于其他需求
use warnings;
use strict;
use feature 'say';
use DateTime;
use DateTime::TimeZone;
my $tz = DateTime::TimeZone->new(name => "local");
say $tz->name(); #--> America/Los_Angeles
my $dt = DateTime->now(time_zone => "local");
say "local: $dt"; #--> local: 2019-06-18T09:57:58
$dt->set_time_zone("UTC");
say "UTC: $dt"; #--> UTC: 2019-06-18T16:57:58
有关详细信息,请参阅文档,至少有关DateTime::TimeZone constructor。
还请注意,他们建议不要在$tz->short_name...
下使用“短”名称(“ EST”)一旦您使用DateTime
,也可能会有偏移量
my $dt = DateTime->now(time_zone => 'local');
say $dt->offset/(60*60); #--> -7
say $dt->strftime("%z"); #--> -0700
方法offset返回以秒为单位的时区偏移量。
我们通常期望的strftime提供格式;文档说:“ 与POSIX标准的任何偏离都可能是一个错误。”完整的时间戳示例:$dt->strftime('%Y-%m-%dT%H:%M:%S%z')
。
答案 1 :(得分:2)
Date :: Manip :: TZ文档的Determining the System Time Zone部分。如果向下滚动,则会发现一个列表,用于确定系统时区的方法(以什么顺序排列)取决于您是在Unix还是Windows下运行。
根据您在问题中发布的内容,它似乎正在正确读取当地时间,但未能确定正确的时区,因此您应该能够通过从TZ列表中查找来找到根本问题。操作系统上使用的识别方法。 (即,对于Unix,先检查$::TZ
,然后检查zone
和TZ
环境设置,再检查/etc/TIMEZONE
,依此类推,直到找到既存在又时区错误的环境列出)