Perl - DateTime 模块 - 如何比较两个 DateTime 的 24 小时延时

Perl - DateTime module - How to compare two DateTime's for a 24 hour time lapse

我将日期时间戳保存到我的数据库中:

2015-02-23T16:59:25

我有一个代表当前时间的新日期时间戳。

2015-02-24T16:59:25

我需要将两者与 DateTime 进行比较,以检查是否已经过了 24 小时。

#!/usr/bin/perl
use strict;
use DateTime;

my $longenough;

Testing123();
exit;
sub Testing123{
my $yesterday = DateTime->now;
$yesterday->add( days => -1 ); 

 #This $yesterday time gets saved to my database.
 #For question purposes, I'll just pass it along instead of from db. 

CheckLapse($yesterday);

if ($longenough eq 'y'){ print qq~24 hours have passed<br />~; }
else{print qq~24 hours have not passed<br />~;}
}

sub CheckLapse{
$yesterday = shift;
my $now = DateTime->now;

# leftovers from many many hours of different attempts from my old bramaged drain

# my $elapse = $now - $yesterday;
# $now->subtract_duration( $yesterday ) ;
# $TimeLapse = $elapse->in_units('seconds'); #Left over from another try
# print "Elapsed time : ".$elapse->in_units('seconds')."m\n";

##  I need to compare the two times and pass $longenough y/n back:

if ($TimeLapse >= [24 hours whatever seconds minutes to do calc]){
$longenough = 'y';
}
else {$longenough = 'n';}
return $longenough;
}
exit;

我已经阅读并阅读了 cpan DateTime 文档并尝试了所有方法,除了显然是正确的解决方案。 我不断收到类似 "Can't call method "yada yada" without a package or object reference" 这样的错误。

有人可以在这里教育我吗?

您可以按如下方式从字符串构造 DateTime 对象:

use DateTime::Format::Strptime qw( );

my $dt_format = DateTiFormat::Strptime->new(
   pattern   => '%Y-%m-%dT%H:%M:%S',
   time_zone => 'local',
   on_error  => 'croak',
);

my $dt = $dt_format->parse_datetime('2015-02-23T16:59:25');

然后你可以像这样检查它是否为 24 小时:

my $now = DateTime->now( time_zone => $dt->time_zone );
if  ($dt->clone->add( hours => 24 ) >= $now) {
   # It's been more than 24 hours.
   ...
}

现在,每次检查是否已过 24 小时时,上面的代码都会做很多工作。如果你重复这样做,你可以使用减少工作量如下:

use DateTime::Format::Strptime qw( );

my $dt_format = DateTime::Format::Strptime->new(
   pattern   => '%Y-%m-%dT%H:%M:%S',
   time_zone => 'local',
   on_error  => 'croak',
);

my $dt = $dt_format->parse_datetime('2015-02-23T16:59:25');
$dt->add( hours => 24 );
my $target_time = $dt->epoch;

然后检查然后简化为

if  ($target_time >= time)
   # It's been more than 24 hours.
   ...
}

您可能需要 ->add( days => 1 )(下一个日历日的同一时间)而不是 ->add( hours => 24 )

DateTime module is enormous and slow, and is a complete toolbox for anything date-time related. Time::Piece 是一个重量更轻的核心模块(因此不需要安装),完全可以胜任这项任务。

下面是使用 Time::Piece

的解决方案演示
use strict;
use warnings;
use 5.010;

use Time::Piece ();
use Time::Seconds 'ONE_DAY';

my ($t1, $t2) = qw/
  2015-02-23T16:59:25
  2015-02-24T16:59:25
/;

my $diff = delta_time($t1, $t2);

say $diff >= ONE_DAY ? 'over one day' : 'less than one day';

sub delta_time {
  my ($t1, $t2) = map Time::Piece->strptime($_, '%Y-%m-%dT%H:%M:%S'), @_;
  return $t2 > $t1 ? $t2 - $t1 : $t1 - $t2;
}

输出

over one day