<[asests][EFT][TruePermalink] assets for EFT a... | [assets][CustomFeed-Script] Web::Scraper for ...>
2008-01-05
■ [perl] DateTime::Format::Relative

現在の日時からの相対的な日時,例えば「今日」「明後日」「先月」「来年」などを取得するためのモジュール。
ただし「明後日」の場合には,単純に現在時刻に2日加算するのではなく,明後日の0時を返す。他の場合も同様に,まず指定された単位以下をtruncateした後に日時の加減算を行う。例えば「2008年1月5日 5時24分43秒」の場合:
- 今日: 2008年1月5日 0時0分0秒
- 明後日: 2008年1月6日 0時0分0秒
- 先月: 2007年12月1日 0時0分0秒
- 来年: 2009年1月1日 0時0分0秒
となる。
フォーマットは「tomorrow」「+2 days」「1 month before」「next year」など。
経緯
Yahoo!Pipesで日時の指定に「today」とか「+1 day」とかできるのを知ってムラムラしたので書いた。これまでYAMLに絶対的な日時を指定しなければならなかったSubscriptionやCustomFeedも,このモジュールがあれば定期実行しやすい日付指定ができるようになるはず。
DateTime/Format/Relative.pm
# author: SweetPotato package DateTime::Format::Relative; use strict; use warnings; our $VERSION = '0.01'; use DateTime; our %op = ( '+' => 'add', '-' => 'subtract', 'after' => 'add', 'later' => 'add', 'before' => 'subtract', 'ago' => 'subtract', 'next' => 'add', 'this' => 'add', # don't care 'prev' => 'subtract', 'previous' => 'subtract', ); our $units = join '|', qw( day week month year hour minute second ); sub parse_datetime { my ($self, $str, %opt) = @_; my ($op, $diff, $unit); $_ = lc($str); s/^\s*|\s*$//g; # +2 day(s) if (/^(\+|-)\s*(\d+)\s+($units)s?$/) { ($op, $diff, $unit) = ($op{$1}, $2, $3); } # 2 day(s) ago elsif (/^(\d+)\s+($units)s?\s+(after|later|before|ago)$/) { ($op, $diff, $unit) = ($op{$3}, $1, $2); } # next month elsif (/^(next|this|prev|previous)\s+($units)$/) { ($op, $diff, $unit) = ($op{$1}, $1 eq 'this' ? 0 : 1, $2); } elsif ($_ eq 'today') { ($op, $diff, $unit) = ('add', 0, 'day'); } elsif ($_ eq 'yesterday') { ($op, $diff, $unit) = ('subtract', 1, 'day'); } elsif ($_ eq 'tomorrow') { ($op, $diff, $unit) = ('add', 1, 'day'); } else { die "parse error: $str"; } DateTime->now(%opt)->truncate(to => $unit)->$op("${unit}s" => $diff); } 1;
コメント
トラックバック - http://plagger.g.hatena.ne.jp/SweetPotato/20080105