yohhoyの日記

技術的メモをしていきたい日記

C++標準ライブラリのタイムゾーン(Time Zone)

C++2a(C++20)標準ライブラリ <chrono> ヘッダに追加される タイムゾーン(Time Zone) サポートについてざっくりメモ。

本記事では簡単のため名前空間std::chronoを省略する。カレンダー(Calendar)については C++標準ライブラリのカレンダー(Calendar) 参照。

まとめ:

  • タイムゾーン時刻(zoned_time)=タイムゾーン指定+ローカル時刻(Time Point)*1
    • 例: auto zt = zoned_time{"Asia/Tokyo", local_days{2020y/7/24} + 13h};
  • タイムゾーン指定=タイムゾーン名 or タイムゾーン(time_zone)構造体。現タイムゾーンの取得(current_zone())やタイムゾーン検索(locate_zone())を提供。
    • 例: auto zt_now = zoned_time{current_zone(), system_clock::now()};
  • UTCタイムゾーン時刻の相互変換、異なるタイムゾーン時刻間の相互変換をサポート。
    • 例1: auto zt_tokyo = zoned_time{"Asia/Tokyo", system_clock::now()};
    • 例2: auto tp_utc = system_clock::time_point{zt_tokyo};
    • 例3: auto zt_paris = zoned_time{"Europe/Paris", zt_tokyo};
  • 夏時間(サマータイム; Daylight Saving Time)サポートあり。
    • 夏時間の開始/終了付近において “存在しないローカル時間*2”、“重複するローカル時間*3” という概念が生じるため、例外nonexistent_local_time, ambiguous_local_timeが提供される。
    • “重複するローカル時間” からUTCへの変換時は、丸めモード(choose::earliest, choose::latest)明示指定で例外発生を回避できる。
    • やはり夏時間は悪い文明!! 粉砕する!!
  • タイムゾーンデータベース(tzdb)はライブラリ埋め込み。タイムゾーン情報・うるう秒(leap seconds)情報から構成される。

ノートC++2a標準ライブラリ準拠するにはタイムゾーンデータベースを内包せざるをえないため、データサイズ肥大化の一因になりそう。更新が必要なデータベースなのは確かだが、C++標準ライブラリに「遠隔(remote)データベースからの情報取得」という文言が入ってくるのはなかなか衝撃的。

関連URL

*1:local_days は特定タイムゾーンと紐づかないローカル時刻の日単位Time point型。

*2:タイムゾーン "America/New_York" のローカル時刻 2016-03-13 02:30:00 は、2016-03-13 02:00:00 EST == 2016-03-13 03:00:00 EDT == 2016-03-13 07:00:00 UTC の隙間に位置するため存在しえない。

*3:タイムゾーン "America/New_York" のローカル時刻 2016-11-06 01:30:00 は、2016-11-06 01:30:00 EDT == 2016-11-06 05:30:00 UTC または 2016-11-06 01:30:00 EST == 2016-11-06 06:30:00 UTC のいずれか。