获得两个Time :: Piece对象之间的分钟差异

时间:2014-03-27 01:48:44

标签: perl datetime

我有代码:

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来自哪里?

2 个答案:

答案 0 :(得分:3)

重现“bug”

出现此问题是因为s​​trptime默认为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只需要使用$nowlocaltime初始化,当然不需要->new()

正如你可以看到一个声称DST而另一个没声明,但日期数学仍然正确完成。通过查看gmtimestrptime_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。