Сначала вам нужно сделать правильное вычитание. Существует delta_md
, delta_days
, delta_ms
и subtract_datetime_absolute
. В зависимости от того, какую единицу вы хотите позже, вам нужно выбрать правильное вычитание. Проблема заключается в том, что не каждая единица позже может быть конвертирована без информации о часовом поясе. Вот почему вам нужно выбрать правильный метод дельта.
Например, день может иметь 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) Вам не нужно (). Эти модули являются ООП и ничего не экспортируют / не импортируют.