我目前正在构建一个处理大量时间相关功能的模块。我正在使用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种东西) 。但这两个都是繁琐的,我的问题基本上是有一种不同的(和更优雅的)方法我可以采取解决这个问题,并且仍然可以将时间回到本地时间使用的数组中,因此它与其余的一致模块?
答案 0 :(得分:2)
my $dt = DateTime->now( time_zone => 'local' );
$dt->subtract( days => 5 );
say $dt->strftime('%Y-%m-%d');
$dt->epoch
返回值localtime
接受。
答案 1 :(得分: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
,因此您应该能够轻松地将其引入现有代码。