0

我目前正在构建一个处理大量时间相关功能的模块。我经常使用 localtime(time),因为它返回的数组 (sec,min,hour,dayofmonth,mon,year,weekday,yearday,isDST) 对于时间戳很有用,并且希望尽可能使用它来保持一致性。

我需要创建一种基于给定时差计算时间的方法(即“5 天前的日期是什么?”之类的)。我目前的想法是将差异设置为“差异数组”(例如 [0,0,0,-5,0,0,0,-5,0])并将其添加到提供新日期的基准时间。但这在边界时间(例如回滚到上个月)和保持一切正确对齐(例如夏令时)方面存在问题。

我的另一个想法是使用 timelocal() 将其转换回时间值,给出一个平坦的差异并将其添加到基本时间以获得结果时间,然后使用 localtime 转换回来使其与模块的其余部分。但这可能是有问题的,因为它可能会不规律地处理潜在的负值。

当然,我可以对第一种方法的数组值进行规范化,或者从时间值中减去一系列值(所以是一个常量列表,Day = 8400,hour = 3600,min = 60 之类的东西)。但这两者都很繁琐,我的问题本质上是我可以采取一种不同(更优雅)的方法来解决这个问题,并且仍然能够将时间恢复到 localtime 使用的数组中,因此它与其余部分一致模块?

4

2 回答 2

2
my $dt = DateTime->now( time_zone => 'local' );
$dt->subtract( days => 5 );
say $dt->strftime('%Y-%m-%d');

$dt->epoch返回一个localtime接受的值。

于 2013-04-02T14:23:39.750 回答
1

一种更优雅的方法是使用基于时间的对象。它们允许您在更高、更抽象的级别上进行计算,这将使您免于处理日/月/年边界之间localtime的所有转换。timelocal

有各种模块可以让你做到这一点。我建议您从Time::Piece(核心的一部分,并且非常快速和轻量级)开始,如果这不足以满足您的需求,则转向更重的东西。

use Time::Piece;    # takes over localtime()
use Time::Seconds;  # use constant ONE_DAY

my $now = localtime();
my $five_days_ago = $now - ONE_DAY * 5;

print $now, "\n";           # same as if you used localtime() w/o Time::Piece
print $now->datetime, "\n"; # 2000-02-29T12:34:56 (ISO 8601)

my $diff = $now - $five_days_ago;
print $diff->pretty, "\n";

Time::Piece以向后兼容的方式覆盖localtime,因此您应该能够轻松地将其引入现有代码。

于 2013-04-02T10:23:38.020 回答