此代码查找今天和固定日期之间的差异。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use DateTime ();
use DateTime::Duration ();
use DateTime::Format::Strptime ();
my $date = "23/05-2022";
my $parser = DateTime::Format::Strptime->new(
pattern => '%d/%m-%Y',
time_zone => 'local',
);
$date = $parser->parse_datetime($date);
my $today = DateTime->today(time_zone=>'local');
my $d = DateTime::Duration->new($today - $date);
print Dumper $d->delta_days;
问题是只输出-22天。
如果我print Dumper $d;
我也可以看到-130个月。
$VAR1 = bless( {
'seconds' => 0,
'minutes' => 0,
'end_of_month' => 'preserve',
'nanoseconds' => 0,
'days' => -22,
'months' => -130
}, 'DateTime::Duration' );
如何让它在几天内输出结果?
否则
print Dumper $d->delta_days + $d->delta_months*30;
并不像一个优雅的解决方案。
答案 0 :(得分:25)
首先,您需要进行正确的减法。存在delta_md
,delta_days
,delta_ms
和subtract_datetime_absolute
。根据您以后想要的单位,您需要选择正确的减法。问题是,并非每个单元都可以在没有time_zone信息的情况下进行转换。这就是你需要选择正确的delta方法的原因。
例如,一天可以有23小时或24小时或25小时,具体取决于时区。因此,您需要指定减法应如何工作。因为你想要几天后,减法需要关注几天,而不是关注几小时。不要使用过载功能,因为它只能做到最合适。
这意味着您需要进行delta_days
减法。
my $dur = $date->delta_days($today);
现在$ dur是DateTime::Duration
个对象。你需要知道,如果可能的话,它总是尽量适合日,周,年,月。这意味着你的日子会在几周和几天内分裂。因为这种转换总是一个常数。
如果您不希望这种“最适合”,则需要调用in_units
方法并将其转换为天数。
my $days = $dur->in_units('days');
但就像我在in_units
之前所说的那样,只有在可能的情况下才能进行转换。使用in_units('hours')
的呼叫不会对此对象起作用,只返回零,因为您无法将天数转换为小时。例如,如果您需要数小时,则需要执行delta_ms
,并且可以在此对象上调用in_units('hours')
完整的例子:
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
use DateTime;
use DateTime::Format::Strptime;
my $date = "23/05-2022";
my $parser = DateTime::Format::Strptime->new(
pattern => '%d/%m-%Y',
time_zone => 'local',
);
$date = $parser->parse_datetime($date);
my $today = DateTime->new(
day => 1,
month => 7,
year => 2011,
time_zone => 'local'
);
my $dur = $date->delta_days($today);
say "Weeks: ", $dur->weeks;
say "Days: ", $dur->days;
say "Absolute Days: ", $dur->in_units('days');
say "Absolute Hours: ", $date->delta_ms($today)->in_units('hours');
该程序的输出是:
Weeks: 568
Days: 3
Absolute Days: 3979
Absolute Hours: 95496
仅供参考:
1)您无需加载DateTime::Duration
加载DateTime
2)你不需要()。这些模块是OOP,不会导出/导入任何内容。
答案 1 :(得分:2)
快速阅读DateTime module doc,我不相信
DateTime::Duration->new($today - $date)
会做你期望的。我相信你需要使用
$dur = $today->subtract_datetime($date)
然而,文档中并未立即清楚$dur
的类型。