前回の
日付表現を便利にするモジュール
(1)
(2)
DateTime ──日付演算を正確に行うモジュール
日付処理の代表的なモジュールとして,DateTimeDateTimeオブジェクトは,newやfrom_メソッドなどで時間を直接指定して作成するか,nowメソッドやtodayメソッドで実行日時から作ることができます。
use DateTime;
my $dt = DateTime->new(
year => 2021,
month => 1,
day => 1,
hour => 0,
minute => 0,
second => 0,
# nanosecond => 0,
time_zone => 'Asia/Tokyo'
);
my $now = DateTime->now(time_zone => 'Asia/Tokyo');
DateTimeオブジェクトは加算や減算の処理が行えますが,Cloneモジュール
use DateTime;
use Clone qw(clone);
my $dt_1 = DateTime->now(time_zone => 'Asia/Tokyo');
my $dt_2 = clone($dt_1);
$dt_2->add(months => 1, days => 1);
演算結果が月末を超える場合の最後の日の合わせ方は,wrap,limit,preserveのいずれかをend_に指定できます。wrapは月末を超えて演算します。limitは月末を超えたら月末に合わせます。preserveは月末を超えたら月末に合わせたうえで,wrapで,preserveです。
$dt->add(months => 1, end_of_month => 'preserve');
また,DateTimeオブジェクトどうしの減算を行う場合,DateTimeオブジェクトのdelta_メソッドに,DateTimeオブジェクトを渡すことで,DateTime::DurationDateTimeオブジェクトのin_メソッドで取り出したい単位を指定します。
use DateTime;
my $dt_1 = DateTime->new( year => 2021, month => 1, day
=> 1, time_zone => 'Asia/Tokyo' );
my $dt_2 = DateTime->new( year => 2021, month => 2, day
=> 1, time_zone => 'Asia/Tokyo' );
my $duration = $dt_2->delta_days($dt_1);
say $duration->in_units('days'); # 差は31日
異なるタイムゾーンのDateTimeオブジェクトどうしの場合は,set_メソッドで一度UTCに変換してから演算を行い,
$dt_1->set_time_zone('UTC');
DateTimeモジュールは,
しかし,DateTimeモジュールは,
閏秒を考慮しない場合は,Time::Pieceモジュールや次項のTime::Momentモジュールなどの比較的軽量なモジュールを検討するとよいです。
Time::Moment ──高速な日付演算モジュール
Time::MomentDateTimeモジュールと似た感覚で扱え,
use Time::Moment;
my $tm = Time::Moment->new(
year => 2021,
month => 1,
day => 1,
hour => 0,
minute => 0,
second => 0,
# nanosecond => 0,
offset => 60 * 9, # 日本時間
);
my $now = Time::Moment->now;
my $utc = Time::Moment->now_utc;
my $epoch = Time::Moment->from_epoch(1000);
Time::Momentオブジェクトは,DateTimeオブジェクトの破壊的な加算や減算とは異なり,Time::Momentオブジェクトが作られる非破壊的な処理を行います。また,plus_や減算するminus_は,
$tm2 = $tm1->plus_months(1); # 1ヶ月を加算
DateTimeモジュールは実行速度がかなり遅いです。BenchmarkモジュールDateTimeモジュールよりTime::Pieceモジュールが約25倍速く,Time::MomentモジュールにいたってはDateTimeモジュールより約140倍速いです。頻繁に日付処理を行う場合は,DateTimeモジュールからTime::Momentモジュールへの移行を検討してもよいでしょう。
use Benchmark qw(cmpthese);
use Time::Moment;
use Time::Piece;
use DateTime;
cmpthese 0, {
'DateTime' => sub {
DateTime->now(time_zone => 'Asia/Tokyo')
},
'Time::Piece' => sub { Time::Piece->localtime },
'Time::Moment' => sub { Time::Moment->now },
};
第66回 モジュールによる時間の多様な取り扱い(2) - Gihyo Jp
Read More
Bagikan Berita Ini
0 Response to "第66回 モジュールによる時間の多様な取り扱い(2) - Gihyo Jp"
Post a Comment