Time::Piece(Time::Seconds)のONE_MONTHでうっかりやってしまった
「2011-10-01 00:00:00」の一ヶ月前のTime::Pieceオブジェクトを取得したいというような場合に「$t -= ONE_MONTH」みたいなコードを書いたら意図しない結果になってしまった。詳しくはhttp://blog.clouder.jp/archives/000409.htmlに書いてある通り。以下はよろしくないサンプルとそれの代替となるコード。
use strict; use warnings; use Time::Piece; use Time::Seconds; use Perl6::Say; for my $month ( 1 .. 12 ) { my $date = sprintf "2011-%02d-01 00:00:00", $month; my $t = Time::Piece->strptime( $date, '%Y-%m-%d %H:%M:%S' ); my $t2 = $t - ONE_MONTH; my $format = '%Y-%m-%d %H:%M:%S'; printf "%s\t%s\n", $t->strftime($format), $t2->strftime($format); } ## 2011-01-01 00:00:00 2010-12-01 13:30:56 ## 2011-02-01 00:00:00 2011-01-01 13:30:56 ## 2011-03-01 00:00:00 2011-01-29 13:30:56 ## 2011-04-01 00:00:00 2011-03-01 13:30:56 ## 2011-05-01 00:00:00 2011-03-31 13:30:56 ## 2011-06-01 00:00:00 2011-05-01 13:30:56 ## 2011-07-01 00:00:00 2011-05-31 13:30:56 ## 2011-08-01 00:00:00 2011-07-01 13:30:56 ## 2011-09-01 00:00:00 2011-08-01 13:30:56 ## 2011-10-01 00:00:00 2011-08-31 13:30:56 ## 2011-11-01 00:00:00 2011-10-01 13:30:56 ## 2011-12-01 00:00:00 2011-10-31 13:30:56
これをTime::Piece::Monthを使って正しくすっきりと書く。
use strict; use warnings; use Time::Piece::Month; use Perl6::Say; for my $month ( 1 .. 12 ) { my $date = sprintf "2011-%02d-01 00:00:00", $month; my $t = Time::Piece->strptime( $date, '%Y-%m-%d %H:%M:%S' ); my $month = Time::Piece::Month->new($t); my $format = '%Y-%m-%d %H:%M:%S'; printf "%s\t%s\t%s\n", $t->strftime($format), $month->next_month->end->strftime($format), $month->prev_month->start->strftime($format); } ## 2011-01-01 00:00:00 2011-02-28 00:00:00 2010-12-01 00:00:00 ## 2011-02-01 00:00:00 2011-03-31 00:00:00 2011-01-01 00:00:00 ## 2011-03-01 00:00:00 2011-04-30 00:00:00 2011-02-01 00:00:00 ## 2011-04-01 00:00:00 2011-05-31 00:00:00 2011-03-01 00:00:00 ## 2011-05-01 00:00:00 2011-06-30 00:00:00 2011-04-01 00:00:00 ## 2011-06-01 00:00:00 2011-07-31 00:00:00 2011-05-01 00:00:00 ## 2011-07-01 00:00:00 2011-08-31 00:00:00 2011-06-01 00:00:00 ## 2011-08-01 00:00:00 2011-09-30 00:00:00 2011-07-01 00:00:00 ## 2011-09-01 00:00:00 2011-10-31 00:00:00 2011-08-01 00:00:00 ## 2011-10-01 00:00:00 2011-11-30 00:00:00 2011-09-01 00:00:00 ## 2011-11-01 00:00:00 2011-12-31 00:00:00 2011-10-01 00:00:00 ## 2011-12-01 00:00:00 2012-01-31 00:00:00 2011-11-01 00:00:00
ほんのちょっとテストする時間をけちった結果は高くつきました。。コードを書けば書くほど自分の粗がぼろぼろと出てきてちょっと鬱。