ちょっとperlやってないと毎回忘れるのでメモ
やりたいこと
やりたいことは単純で、
○○年○○月○○日○○時過ぎたらこの処理やる
時間の比較にはTime::Pieceを使う
みたいなことですけど、毎回同じトコで間違って調べては対応って繰り返してるので
メモって自分をいましめようと思った次第です。。orz
さっそく
毎回間違うソース
timepice_test.pl
#!/usr/bin/perl use strict; use warnings; use Time::Piece; my $tp_now = localtime; my $target_datetime = '2013-12-12 19:22:00'; my $tp_target = Time::Piece->strptime($target_datetime, '%Y-%m-%d %H:%M:%S'); warn "now datetime :" .$tp_now->datetime; warn "target datetime :" .$tp_target->datetime; warn "\n"; warn "now timezone :" .$tp_now->strftime('%Z'); warn "target timezone :" .$tp_target->strftime('%Z'); warn "\n"; warn "now epoch :" .$tp_now->epoch; warn "target epoch :" .$tp_target->epoch; warn "\n"; if( $tp_now > $tp_target ) { warn "hogehoge"; } else { warn "piyopiyo"; }
毎回間違う結果
今の時間が2013-12-12 19:23:00分だったとすると、期待する結果としては最後に'hogehoge'が出て欲しいです。
が、結果はこうなります
# perl timepice_test.pl now datetime :2013-12-12T19:22:47 at timepice_test.pl line 12. target datetime :2013-12-12T19:22:00 at timepice_test.pl line 13. now timezone :JST at timepice_test.pl line 16. target timezone :JST at timepice_test.pl line 17. now epoch :1386843767 at timepice_test.pl line 20. target epoch :1386876120 at timepice_test.pl line 21. piyopiyo at timepice_test.pl line 30.
datetimeの値はnow > targetで、タイムゾーンも'JST'ですが
epochの値はnow < targetで最終結果も'piyopiyo'となってしまいます
正しい対応
正しいソース
原因の詳細は、自分が毎回見る他の方が書いてくれてる記事にあるので割愛しますが
対応方法はTime::Piece->strptimeをさらにlocaltimeでかこってやればOKです
my $tp_target = Time::Piece->strptime($target_datetime, '%Y-%m-%d %H:%M:%S'); ↓ my $tp_target = localtime(Time::Piece->strptime($target_datetime, '%Y-%m-%d %H:%M:%S'));
ちなみにいつも参考にさせて頂いてるのはこちら
→Time::Piece とタイムゾーンの甘い罠
正しい結果
# perl timepice_test.pl now datetime :2013-12-12T19:28:51 at timepice_test.pl line 12. target datetime :2013-12-12T19:22:00 at timepice_test.pl line 13. now timezone :JST at timepice_test.pl line 16. target timezone :JST at timepice_test.pl line 17. now epoch :1386844131 at timepice_test.pl line 20. target epoch :1386843720 at timepice_test.pl line 21. hogehoge at timepice_test.pl line 26.
補足
いつも参考にさせて頂いてる記事にも記載がありますが、
Time::Pieceのバージョンが1.15以下(含む)だとlocaltimeでかこってもダメ
みたいですので気をつけましょう
自分が最初に試した環境も'1.14'でうまくいきませんでしたw
# vi /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/Time/Piece.pm
---- 省略 ----
our $VERSION = '1.14';
--------------