Perlで日時のタイムゾーンを変更する
前回はPHPでの日時情報のタイムゾーン操作を取り上げましたが、今度はPerlで同じことをしてみます。
Perlでの日時操作は5.10からコアに組み込まれたTime::Pieceを利用するケースが一般的ですが、タイムゾーン操作を伴う場合はDateTimeとDateTime::TimeZoneを利用します。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | use strict; use warnings; use utf8; use DateTime; use DateTime::TimeZone; my $tz = DateTime::TimeZone->new( 'name' => 'local' ); my $dt = DateTime->now( 'time_zone' => $tz ); print $dt ->datetime, "\n" ; # YYYY-MM-DD HH:mm:ssで表示 print $dt ->strftime( '%G-%m-%dT%T%z' ), "\n" ; # タイムゾーンを表示に含める場合 # UTCへ変換 $dt ->set_time_zone( 'UTC' ); print $dt ->datetime, "\n" ; # ロンドンのタイムゾーンへ変換 $dt ->set_time_zone( 'Europe/London' ); print $dt ->datetime, "\n" ; # N.Y.のタイムゾーンへ変換 $dt ->set_time_zone( 'America/New_York' ); print $dt ->datetime, "\n" ; 1; |
もちろんサマータイムは考慮してくれます。
前のサンプルのように前もってDateTime::TimeZoneオブジェクトを作成して、DateTimeのコンストラクトの際に引数としてDateTime::TimeZoneオブジェクトを渡してやる方が処理が早いのですが、単純に任意のタイムゾーンの現在時刻を表示させるなら
1 | print DateTime->now( 'time_zone' => 'Europe/Paris' )->datetime; |
という書き方もできます。
PerlのDateTimeの場合も当然のように、現在日時でなくてもオブジェクトが作成できます。DateTimeでオブジェクトを作成する場合、
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | use strict; use warnings; use utf8; use DateTime; $dt = DateTime->new( time_zone => 'Asia/Tokyo' , year => 2011, month => 9, day => 15, hour => 9, minute => 0, second => 0 ); print $dt ->datetime, "\n" ; 1; |
としますが、インターネット上でよく使われる日時記述からDateTimeオブジェクトを作成する場合はDateTime::Format::HTTPを利用して、
1 2 3 4 5 6 7 8 | use strict; use warnings; use utf8; use DateTime::Format::HTTP; my $dt = DateTime::Format::HTTP->parse_datetime( '2011-09-15T09:00:00Z' ); print $dt ->set_time_zone( 'Asia/Tokyo' )->datetime, "\n" ; 1; |
と書くと、いちいち日付情報を分割せずに済むので便利です。
特定の用途のために任意の書式で出力したい場合、strftimeメソッドでちまちま指定すれば目的が適いますが、よく使いそうな書式はCPANで公開されてることがよくあります。
例えばメールヘッダー用。
01 02 03 04 05 06 07 08 09 10 | use strict; use warnings; use utf8; use DateTime::Format::HTTP; use DateTime::Format::Mail; my $dt = DateTime->now( 'time_zone' => 'Asia/Tokyo' ); my $mail_format = 'DateTime::Format::Mail' ; print $mail_format ->format_datetime, "\n" ; 1; |
こんな感じに書けます。