一度忘れるとなかなか思い出せないのでメモ。
YYYY-MM-DDTHH:mm:ss
のようなISO 8601の日付を扱う場合は、一度エポック秒にしてから、DateTimeで変換します。
エポック秒には、Time::PieceやHTTP::Dateを使い、タイムゾーンの設定と秒から日付への変換には、DateTimeを使います。
ISO 8601に変換する場合は、DateTime::Format::ISO8601::Format を使用すると簡単です。
#!/usr/bin/perl use strict; use warnings; use feature qw/say/; use DateTime; my $iso_8601 = '2018-12-31T09:46:49Z'; # HTTP::Date use HTTP::Date qw/str2time/; my $iso_8601_epoch = str2time($iso_8601, 'UTC'); my $dt = DateTime->from_epoch(epoch => $iso_8601_epoch); say $dt->set_time_zone('Asia/Tokyo'); # Time::Piece use Time::Piece; $iso_8601_epoch = Time::Piece->strptime($iso_8601, '%Y-%m-%dT%H:%M:%SZ')->epoch; $dt = DateTime->from_epoch(epoch => $iso_8601_epoch); say $dt->set_time_zone('Asia/Tokyo'); # ISO 8601 use DateTime::Format::ISO8601::Format; my $format = DateTime::Format::ISO8601::Format->new(); say $format->format_datetime($dt);