Masteries

技術的なことや仕事に関することを書いていきます.

小ネタ: PerlのDateTime::Durationで日数の差を出すのはdays... ではなくdelta_days

小ネタです. Perlにおいて時間を扱うライブラリの1つにDateTimeがあります.

metacpan.org

DateTimeには, DateTime::Durationというパッケージがあり, これはある時間Aとある時間Bの間の"期間"を表すものです.

metacpan.org

さて, 今次のようなコードで2020年7月22日と, 2020年7月1日の間の期間(DateTime::Duration)を取得したとします.

my $dt1 = DateTime->new(
    year  => 2020,
    month => 7,
    day   => 22,
);
my $dt2 = DateTime->new(
    year  => 2020,
    month => 6,
    day   => 5,
);

my $d = $dt1->subtract_datetime($dt2);

...なんとなく, 「じゃあ, ここから日数の差を出すならdaysか...?」と思ってdaysメソッドを使うと, 次のような結果になります.

print $d->days; # => 3

結論から言うと, DateTime::Durationのdaysや, months/weeksなどのメソッドは, 「より大きな単位に変換した後の余り」を出すようになっています.

These methods return numbers indicating how many of the given unit the object represents, after having done a conversion to any larger units. For example, days are first converted to weeks, and then the remainder is returned. These numbers are always positive.

つまりこの「3」という数字は, 実際の日数の差17から, より大きな単位である週(= 7日)に変換した余りを表す, ということです: 17 - 14 = 3

実際に, 先の$dt1, $dt2の差となる日数を取得するには, 次のようにdelta_daysを使う必要があります.

print $d->delta_days; # => 17

更に余談ですが, DateTime::Durationにおいてdelta_系のメソッドはdelta_months, delta_days, delta_minutes, delta_seconds, delta_nanosecondsのみが提供されており, delta_hoursは存在しない点には注意しましょう(1敗).