我有一个函数我尝试使用Perl中的DateTime模块重新创建:
$x=dates_difference($year,$month,$day,$cyear,$curmon,$cmday)
给出两个日期,当前日期/时间格式为:$ cyear,$ cmon,$ cmday(年份,月份编号,月份日期编号)和另一个早期格式相同的日期:$ year ,$ month,$ day,我想返回两个日期之间的天数。我不需要它是100%精确的,只要它是+/-一两天所以时间和时区并不重要。
我一直在阅读各种例子,并且找不到任何明确的内容。
我试过了:
$x = $dtcurrent->subtract_datetime_absolute($dt1);
并收到错误DateTime::Duration does not overload comparison. See the documentation on the compare() method for details.
示例:
$x = $dtcurrent->delta_days($dt1);
if ($x > 30) ...
它似乎没有返回我可以在数字比较中使用的数字。
答案 0 :(得分:1)
您想使用delta_days
。
sub dates_difference {
my ($year1, $month1, $day2, $year2, $mon2, $day2) = @_;
my $dt1 = DateTime->new( year => $year1, month => $month1, day => $day1, time_zone => 'floating' );
my $dt2 = DateTime->new( year => $year2, month => $month2, day => $day2, time_zone => 'floating' );
return $dt2->delta_days($dt1)->in_units('days');
}
以下效率更高:
sub dates_difference {
my ($year1, $month1, $day2, $year2, $mon2, $day2) = @_;
my $dt1 = DateTime->new( year => $year1, month => $month1, day => $day1, time_zone => 'floating' );
my $dt2 = DateTime->new( year => $year2, month => $month2, day => $day2, time_zone => 'floating' );
return abs( ( $dt2->local_rd_values )[0] - ( $dt1->local_rd_values )[0] );
}
如果您希望对差异进行签名,请使用以下命令:
sub dates_difference {
my ($year1, $month1, $day2, $year2, $mon2, $day2) = @_;
my $dt1 = DateTime->new( year => $year1, month => $month1, day => $day1, time_zone => 'floating' );
my $dt2 = DateTime->new( year => $year2, month => $month2, day => $day2, time_zone => 'floating' );
return ( $dt2->local_rd_values )[0] - ( $dt1->local_rd_values )[0];
}
答案 1 :(得分:1)
使用核心Time::Piece
模块。它比DateTime
重量轻得多,并且做了所有必要的事情
以下是您的一些示例代码
use strict;
use warnings 'all';
use feature 'say';
use Time::Piece ();
my $x = dates_difference(2017, 1, 1, 2016, 5, 9);
say "$x days until the New Year";
sub dates_difference {
my ($y, $m, $d, $cy, $cm, $cd) = @_;
my $date = Time::Piece->strptime("$y $m $d", '%Y %m %d');
my $cdate = Time::Piece->strptime("$cy $cm $cd", '%Y %m %d');
($date - $cdate)->days;
}
237 days until the New Year
答案 2 :(得分:0)
将代码行组装成示例:
my $dtcurrent = DateTime->new(
year => 2016,
month => 5,
day => 9,
);
my $old = DateTime->new(
year => 2016,
month => 1,
day => 1,
);
(我使用固定的$dtcurrent
来更简单地解释计算结果。生产中应该$dtcurrent = DateTime->now
。)
my $distance = $old->delta_days($dtcurrent);
$distance
是DateTime::Duration
对象,具有不同的属性:
print $distance->years;
0
毫不奇怪:2016年 - > 2016年是0年的差异。
print $distance->months;
0
print $distance->days;
3
发生什么事了? DateTime
手册说:
“delta_days()”方法返回仅包含天数的持续时间。
不是你的预期。但请尝试->in_units
:
print $distance->in_units('days');
129
替代:日期::计算
对于此用例,我更喜欢Date::Calc
:
use Date::Calc qw(Delta_Days Today);
print Delta_Days(Today(), 2016, 1, 1);
-129
交换Today()
和日期以获得正数。 Today()
也可能被另一个$year, $month, $day
替换。
替代:时间戳
use Time::Local qw( timegm ); # Core module
my ($year_now, $month_now, $day_now) = ( localtime(time) )[5,4,3];
my $ts = timegm($year, $month, $day, 0, 0, 0);
my $ts_now = timegm($year_now, $month_now, $day_now, 0, 0, 0);
my $days = int(abs(($ts_now - $ts)) / (24*60*60));
timegm
与gmtime
相反:将日期部分转换为时间戳。由于所有gmtime天都有24 * 60 * 60秒,我们可以通过以gmt查找这些日期的时间戳,计算差异,然后除以24 * 60 * 60来查找两个日期之间的天数。这显然非常复杂且容易出错。
答案 3 :(得分:0)
在这里,我提出的似乎有用......
use DateTime;
my $dt_now = DateTime->now( time_zone => 'local' )->set_time_zone('floating');
my $dt1 = DateTime->new(
year => $year,
month => $month,
day => $day,
time_zone => 'floating',
);
my $days = $dt_now->delta_days($dt1)->in_units('days');