Perl epoch在两台不同的机器上返回不同的值(UTC和CET)

Perl epoch在两台不同的机器上返回不同的值(UTC和CET),perl,time,timezone,Perl,Time,Timezone,我有两台linux机器,它们需要运行perl脚本并访问数据库。 由于任何原因,日期本身是正确的,但是从Perl返回的历元有1小时的差异,这导致在一台机器上有UTC历元时间戳,而在另一台机器上有想要的CET 日期: 2012年12月11日星期二13:34:09欧洲中部时间 日期B: 2012年12月11日星期二13:33:20欧洲中部时间 为了检查发生了什么,我建立了一个极简主义的例子。 脚本使用Time::HiRes并收集localtime->epoch来生成日期。 我构建了一个最低限度的以下脚

我有两台linux机器,它们需要运行perl脚本并访问数据库。 由于任何原因,日期本身是正确的,但是从Perl返回的历元有1小时的差异,这导致在一台机器上有UTC历元时间戳,而在另一台机器上有想要的CET

日期:

2012年12月11日星期二13:34:09欧洲中部时间

日期B:

2012年12月11日星期二13:33:20欧洲中部时间

为了检查发生了什么,我建立了一个极简主义的例子。 脚本使用Time::HiRes并收集localtime->epoch来生成日期。 我构建了一个最低限度的以下脚本来输出行为:

#/usr/bin/perl
#
use Time::HiRes qw(time);
use Time::Piece;
#
my $date = Time::Piece->strptime(localtime->epoch,"%s");
print "$date->datetime"."\n";
print $date->tzoffset."\n";
print $date->epoch."\n";
输出机器A:

2012年12月11日星期二12:35:43->datetime 0 1355229343

输出机器B:

2012年12月11日星期二13:34:25->datetime 0 1355232865


所以,正如你看到的,一定是时区出了问题。时间相差一小时。但是我不知道在哪里查找以及配置什么,因为日期本身输出正确的时间。

我建议您尝试使用
gmtime
而不是
localtime


没有帮助:

>perl -MTime::Piece -E"say Time::Piece->strptime(localtime->epoch,'%s')->epoch;"
1355239881

>perl -MTime::Piece -E"say Time::Piece->strptime(gmtime->epoch,'%s')->epoch;"
1355239881

>perl -E"say time"
1355239881

这似乎是
Time::Piece->strtime(字符串,格式)
中的一个bug。以下是相关代码:

sub strptime {
    my $time = shift;
    my $string = shift;
    my $format = @_ ? shift(@_) : "%a, %d %b %Y %H:%M:%S %Z";
    my @vals = _strptime($string, $format);
让我们从这里开始<代码>\u strtime是操作系统的。它似乎返回了当地时间,尽管在任何地方都没有记录

#    warn(sprintf("got vals: %d-%d-%d %d:%d:%d\n", reverse(@vals)));
    return scalar $time->_mktime(\@vals, (ref($time) ? $time->[c_islocal] : 0));
好的,我们使用
\u mktime
方法将
\u strtime
的输出转换为
Time::Piece
对象。第二个参数是
\u mktime
是否应解释为本地时间或UTC。当调用为
Time::Piece->strptime(字符串,格式)
时,
ref($Time)
将为false,因此
\u mktime
将被调用为
$islocal=0
,即
\u strptime
返回UTC时间。这是错误的,我们发现了错误。(我对C时间函数的了解还不够,不知道该怎么做。)

因此,您必须使用
localtime->strptime(字符串,格式)
。除此之外,由于
\u mktime
中的另一个错误,该模块的旧版本仍然会失败(我的发行版是1.15版,该版本仍然存在漏洞,但在1.20中已修复)

对于
%s
,这甚至不是一个奇怪的问题。任何
Time::Piece->strtime
调用都会发生这种情况:

$ perl -MTime::Piece -E'say $x=Time::Piece->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355220000
Tue Dec 11 04:00:00 2012
$ perl -MTime::Piece -E'say $x=localtime->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355220000
Tue Dec 11 04:00:00 2012
$ export PERL5LIB=Time-Piece-1.20/blib/lib:Time-Piece-1.20/blib/arch
$ perl -MTime::Piece -E'say $x=Time::Piece->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355220000
Tue Dec 11 04:00:00 2012
$ perl -MTime::Piece -E'say $x=localtime->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355241600
Tue Dec 11 10:00:00 2012

perl-le'print time'
提供了什么?您的脚本没有使用time::HiRes。(它加载模块,但不使用它。)这没有帮助。比较
perl-E“say time”
,这是正确的值。
$ perl -MTime::Piece -E'say $x=Time::Piece->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355220000
Tue Dec 11 04:00:00 2012
$ perl -MTime::Piece -E'say $x=localtime->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355220000
Tue Dec 11 04:00:00 2012
$ export PERL5LIB=Time-Piece-1.20/blib/lib:Time-Piece-1.20/blib/arch
$ perl -MTime::Piece -E'say $x=Time::Piece->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355220000
Tue Dec 11 04:00:00 2012
$ perl -MTime::Piece -E'say $x=localtime->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x'
1355241600
Tue Dec 11 10:00:00 2012