我有代码:
use Time::Piece;
use Time::Seconds;
my $timespan = $latest_time - $timestamp;
print $latest_time . "\n";
print $timestamp . "\n";
print $timespan->minutes;
其中$ latest_time = Time :: Piece-> new;和$ timestamp = Time :: Piece-> strptime();
我得到了结果:
Thu Mar 27 09:40:19 2014
Thu Mar 27 09:40:00 2014
-479.683333333333
出了什么问题? $ timespan应该有0分钟,对吗? -479来自哪里?
答案 0 :(得分:3)
重现“bug”
出现此问题是因为strptime默认为UTC而不是本地时区。这可以在下面的代码中演示,该代码占用当前时间,将其打印出来,然后重新分析并显示差异:
use strict;
use warnings;
use Time::Piece;
my $now = Time::Piece->new();
print $now->strftime(), "\n";
my $fmt = "%Y-%m-%d %H:%M:%S";
my $nowstr = $now->strftime($fmt);
my $parsed = Time::Piece->strptime("$nowstr", $fmt);
print "($nowstr)\n";
print $parsed->strftime(), "\n";
my $diff = $now - $parsed;
print $diff->hours, " hours difference\n";
输出:
Wed, 26 Mar 2014 21:42:08 Pacific Daylight Time
(2014-03-26 21:42:08)
Wed, 26 Mar 2014 21:42:08 UTC
7 hours difference
一个hackish解决方案 - 将解析时间作为本地读取
现在,在黑客攻击中,我在草莓perl系统上发现了一个潜在的 hack 。通过这样调用strptime
:$now->strptime
。
my $nowstr = "2014-03-26 21:51:00"; #$now->strftime($fmt);
my $parsed = $now->strptime("$nowstr", $fmt); #Time::Piece->strptime("$nowstr", $fmt);
print "($nowstr)\n";
print $parsed->strftime(), "\n";
my $diff = $now - $parsed;
print $diff->hours, " hours difference\n";
为了确认strptime
实际上是在使用我设定的时间,我给了它一个在当前时间前6分钟的时间。输出如下:
Wed, 26 Mar 2014 21:57:00 Pacific Daylight Time
(2014-03-26 21:51:00)
Wed, 26 Mar 2014 21:51:00 Pacific Standard Time
0.1 hours difference
解析的时间将继承c_islocal
的{{1}}值。 $now
只需要使用$now
或localtime
初始化,当然不需要->new()
。
正如你可以看到一个声称DST而另一个没声明,但日期数学仍然正确完成。通过查看gmtime
,strptime
和_mktime
的来源,我能够弄清楚这个黑客。
希望至少我重现错误的代码对于new
有更多经验的人会有所帮助,我会喜欢更好的解决方案。
答案 1 :(得分:0)
当我对strftime("%H:%M:%S %Z")
和$latest_time
使用$timestamp
时,它们都显示相同的时区,但$latest_time - $timestamp
操作显示时区之间存在差异,因为tobyink指向出。这可能是Time :: Piece模块中的错误。
所以Time::Piece->new;
似乎获得当前的机器时间,包括时区。
因此,当我使用Time::Piece->new
来修复时区问题时,我会在Time::Piece->strptime();
中修复时区或包含时区值。感谢您提供的信息,tobyink。