Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何使用timelocal和localtime根据给定的差异计算时间?_Perl - Fatal编程技术网

Perl 如何使用timelocal和localtime根据给定的差异计算时间?

Perl 如何使用timelocal和localtime根据给定的差异计算时间?,perl,Perl,我目前正在构建一个模块,处理许多与时间相关的函数。我经常使用localtime(time),因为它返回的数组(sec、min、hour、dayofmonth、mon、year、weekday、yearday、isDST)对时间戳很有用,并且希望尽可能使用它来保持一致性 我需要创建一种基于给定时差计算时间的方法(例如“5天前的日期是什么?”之类的东西)。我目前的想法是将差异设置为一个“差异数组”(例如[0,0,0,-5,0,0,0,-5,0]),并将其添加到basetime中以给出一个新的日期。但

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

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

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


当然,我可以对第一个方法的数组值进行标准化,或者从时间值中减去一系列值(比如一系列常量,Day=8400,hour=3600,min=60之类)。但这两个问题都很棘手,我的问题是,我是否可以采取不同的(更优雅的)方法来解决这个问题,并且仍然能够将时间返回到localtime使用的数组中,以便与模块的其余部分保持一致?

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

有多种模块可供您使用。我建议你从(核心的一部分,也非常快速和轻量级)开始,如果这还不足以满足你的需要,就换成更重的

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
,因此您应该能够轻松地将其引入现有代码。

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

my $dt = DateTime->now( time_zone => 'local' );
$dt->subtract( days => 5 );
say $dt->strftime('%Y-%m-%d');
有多种模块可供您使用。我建议你从(核心的一部分,也非常快速和轻量级)开始,如果这还不足以满足你的需要,就换成更重的

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
,因此您应该能够轻松地将其引入现有代码中

my $dt = DateTime->now( time_zone => 'local' );
$dt->subtract( days => 5 );
say $dt->strftime('%Y-%m-%d');
$dt->epoch
返回一个值
localtime
接受


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

您可能需要使用DateTime模块,DateTime::Duration
timelocal
不能用于日期算术。提供超出范围的值有时会给出不正确的结果。并非所有日期都有86400秒,因此不,您不能使用这样的常量。您可能需要使用DateTime模块,并且DateTime::Duration
timelocal
不能用于日期算术。提供超出范围的值有时会给出错误的结果。不是所有的日子都有86400秒,所以不,你不能使用这样的常数。这有时会给出错误的答案。并非所有的日子都有
一天
秒。如果要考虑时区、夏令时、闰秒等,日期/时间的数学可能会非常复杂。
日期时间
是处理这类问题的黄金标准。尽管如此,这段代码满足了原始问题的要求。我也说过,如果不够的话,你可以用更重的东西。这有时会给出错误的答案。并非所有的日子都有
一天
秒。如果要考虑时区、夏令时、闰秒等,日期/时间的数学可能会非常复杂。
日期时间
是处理这类问题的黄金标准。尽管如此,这段代码满足了原始问题的要求。我也说过,如果不够的话,你可以用更重的东西。