@kyanny's blog

私は天才ではありません。ただ、人より長く一つの事と付き合っていただけです - アインシュタイン

DateTime::Set と DateTime::Span の使い方がやっとわかった

DateTime::Set を普通に from_datetimes() で作って iterator でまわしたり as_list でリストを受け取っても、 start と end のふたつの日時しかなくて範囲の日付全部を作ることができず残念だった。 perldoc を熟読して、 from_recurrence() を使えば良いことがわかった。

こんな風にすると、 @dt には $start から $end までの範囲の日時を表す DateTime オブジェクトが入る。 ->add(days => 1) はおまじない的というか、 recurrence で指定する無名サブルーチンは DateTime オブジェクトを一つ受け取り、 The recurrence must return the next event after that object. ということらしい。

my $span = DateTime::Span->from_datetimes(start => $start, end => $end);
my $set = DateTime::Set->from_recurrence(
    span => $span,
    recurrence => sub {
        return $_[0]->truncate(to => 'day')->add(days => 1);
    },
);
my @dt = $set->as_list;

あとで参照できるように、 GitHub - kyanny/datetime-set-example: DateTime::Set and DateTime::Span example code. にサンプルコードを置いた。これで今度こそ、 until ($end->epoch == $start->epoch) { push @date, $start->clone->ymd; $start->add(days => 1); } みたいなコードをコピペしなくて済みそう。