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



我有两台linux机器,它们需要运行perl脚本并访问数据库。不管出于什么原因,日期本身是正确的,但从Perl返回epoch有1个小时的差异,导致一台机器上有UTC epoch时间戳,而另一台机器则有所需的CET。

日期A:

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

日期在B:

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

为了检查发生了什么,我构建了一个极简主义的例子。脚本使用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->日期时间01355229343

输出机器B:

2012年12月11日星期二13:34:25->日期时间01355232865

所以,正如你所看到的,时区一定有问题。随小时而不同。但我不知道该去哪里看,也不知道该配置什么,因为日期本身会输出正确的时间。

这似乎是Time::Piece->strptime(STRING, FORMAT)中的一个错误。这是有问题的代码:

sub strptime {
my $time = shift;
my $string = shift;
my $format = @_ ? shift(@_) : "%a, %d %b %Y %H:%M:%S %Z";
my @vals = _strptime($string, $format);

让我们从这里开始。_strptime是操作系统的本机strptime函数。它似乎回到了当地时间,尽管任何地方都没有记录。

#    warn(sprintf("got vals: %d-%d-%d %d:%d:%dn", reverse(@vals)));
return scalar $time->_mktime(@vals, (ref($time) ? $time->[c_islocal] : 0));

好的,我们使用_mktime方法将_strptime的输出转换为Time::Piece对象。第二个参数是_mktime应该解释为本地时间还是UTC。当调用为Time::Piece->strptime(STRING, FORMAT)时,ref($time)将为false,因此_mktime将使用$islocal=0调用,即_strptime返回UTC时间。这是错误的,我们已经发现了错误。(我对C时间函数的了解还不够,不知道该怎么做。)

}

所以你必须使用localtime->strptime(STRING, FORMAT)。但由于_mktime中的另一个错误,这在旧版本的模块上仍然会失败(我的发行版是1.15版本,它仍然被破坏,但在1.20中修复了)

这甚至不是%s特有的奇怪问题。任何Time::Piece->strptime调用都会发生这种情况:

$ 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

我建议您尝试使用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

相关内容

  • 没有找到相关文章

最新更新