此代码查找今天和固定日期之间的差异。

#!/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;

不像是一种优雅的解决方案。

最佳答案

首先,您需要进行正确的减法。存在delta_mddelta_daysdelta_mssubtract_datetime_absolute。根据您以后想要的单位,您需要选择正确的减法。问题在于,并非每个单元在没有time_zone信息的情况下都可以转换。这就是为什么您需要选择正确的增量方法的原因。

例如,一天可以有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,不会导出/导入任何内容。

09-27 17:09