"Australia/Lord_Howe" は最も奇妙なタイムゾーン
(ssoready.com)- タイムゾーンは複雑だが、コンピュータがこれを実装しなければならないため、奇妙さは有限の範囲に収まる。
Asia/Kathmanduは UTC から見て変則的なオフセットを持つ。Africa/Casablancaはタイムゾーンモデルにうまく当てはまらないため、ハードコードされている。America/Nuukは -01:00 からサマータイムを開始する。Africa/CairoとAmerica/Santiagoは 24時(0時ではない)にサマータイムを開始する。Australia/Lord_Howeは最も奇妙なサマータイム規則を持つ。
PGXIIREAM: 教皇グレゴリウス13世がすべてを支配している
- 世界の大半はグレゴリオ暦に基づく時間システムを使っている。
- グレゴリオ暦は、年間を通して太陽の位置を一定に保つのに非常に有用である。
- UTC はグレゴリオ暦を現代的に公式化したものであり、世界中がこれを基準に時刻を設定している。
うるう秒は重要ではない
- 地球の自転は遅くなっており、それを補正するためにうるう秒が追加される。
- 多くのプログラミング言語では61秒を表現しないため、うるう秒は無視してよい。
- クラウドプロバイダは、うるう秒の間に時計をゆっくり進めることで問題を解決している。
奇妙なタイムゾーン
Asia/Kathmandu は変則的なオフセットを持つ
- ネパールは UTC より 5時間45分進んでいる。
- コンピュータは IANA タイムゾーンデータベースを通じてこの情報を知ることができる。
PDT や CET のような文字列には意味がない
- タイムゾーン識別子は曖昧なことがあり、多くのタイムゾーンが同じ識別子を共有している。
サマータイムのあるタイムゾーンはどのように表現されるのか?
- サマータイムの切り替え規則は複雑であり、コンピュータはそれに基づいて現地時刻を計算する。
Africa/Casablanca と Asia/Gaza は月に従うが、タイムゾーンは太陽に従う
- モロッコとガザはラマダンに合わせてサマータイムを調整しており、これはハードコードされている。
America/Nuuk は -1時にサマータイムへ切り替わる
- グリーンランドはヨーロッパと同じ時点でサマータイムを開始するが、現地時間では -1時に始まる。
America/Santiago と Africa/Cairo は 24時に切り替わる
- これらのタイムゾーンは 24時にサマータイムへ切り替わり、それは翌日にまたがることを意味する。
Australia/Lord_Howe は最も奇妙なサマータイム切り替えを持つ
- ロード・ハウ島では30分のサマータイム切り替えがある。
GN⁺ のまとめ
- タイムゾーンは複雑だが、コンピュータがこれを実装しなければならないため、奇妙さは有限の範囲に収まる。
Australia/Lord_Howeは30分のサマータイム切り替えを持つ、最も独特なタイムゾーンである。- この記事はタイムゾーンの複雑さを理解するのに役立ち、プログラマにとって興味深い内容になりうる。
- 類似した機能を持つプロジェクトとして
tzdbがある。
1件のコメント
Hacker Newsのコメント
tzデータベースでいちばん面白い部分は、ビッグバン時点の推定値が入っていて、ビッグバン以前に発生するタイムゾーン遷移は計算しないようになっていること
https://github.com/eggert/tz/commit/b22d459a367f4d01b10f6f6b... のコミットメッセージも「ビッグバン以前のタイムスタンプは物理的に疑わしいので生成しないようにしよう」という趣旨で、ほどなく別コミットでビッグバン以前のうるう秒も禁止された
dateにおける過去の日付の意味を扱った長い man ページがあった15世紀ごろの例とともに、ある王が特定の週や月を気に入って繰り返すよう命じたり、別の王が特定の週を嫌って暦から消したりした、という話が載っていてかなり目を開かされる読み物だったが、今は見つからない
言い換えると、「ビッグバン以前の瞬間はこのライブラリのスコープ外なので、あるアルゴリズムがビッグバン以前でのみ誤った値を返すなら、そのアルゴリズムは受け入れ可能で、改善や置き換えは不要だ」という結論になる
その部分はバグに対する効用があまり大きく見えず、tzdb の汚い複雑さの大半は
zicにある。ときどきzicが他の人たちの依存先になりうる成果物でなければ、もっとよかったのにと思うタイムゾーン理論が古びる前に、タイムゾーン自体が消えてくれればいいのに
いちばん変なタイムゾーンは Africa/Addis_Ababa だと思う。肝心の エチオピアの現地の人々 はその方式に従っていない
現地では時刻を6時間ずらして、夜明けである午前6時に AM サイクルが始まり、日暮れである午後6時に PM サイクルが始まる
https://en.wikipedia.org/wiki/Time_in_Ethiopia
同様に一日は午後6時、thenashara で終わる。直感的には英語圏の時計よりずっと筋が通っていて、言語の中に埋め込まれているので時刻の混同もまれ
https://en.wikipedia.org/wiki/Ethiopian_calendar
エチオピア暦 は30日ある12か月と、第13の月を構成する5日または6日の閏日的な日付から成る
https://en.wikipedia.org/wiki/Roman_timekeeping
英語圏でも昔は3月25日に年が変わっていた: https://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750#...
どちらも技術的には tzdb の対象ではない。tzdb が扱うのは市民時刻であって、暦やほかの計算法まで扱うわけではない
Asia/Jerusalemの変わった点は、夏時間 が政教分離の問題と大きく絡んでいること。宗教的な人々は、日没に始まる祝祭日に合わせて勤務日が都合よくなることを望むそのため2000年代半ばまで何十年ものあいだ、夏時間は宗教政党と世俗政党のあいだの毎年の交渉の結果で、切り替え日の直前になってようやく決まり、問題が頻発していた
いまでも Rosh HaShanah に夏時間が終わらないようにする例外が入っていて、そのせいで将来ルールが複雑に見えるのだと思う
EU が最終的に廃止に成功すれば追随するかもしれない
だから夏時間によって、もともと遅い時間に終わる行事がさらに遅くなるのを望まない。また Yom Kippur の断食日には、断食が1時間早く終わってほしいという事情もあった。これらの日付に合わせようとすると夏時間の期間が短くなりすぎるため、交渉が必要になっていた
「プログラミング言語は61秒の分を表現できない」というのは、実は事実ではない。すでに誰かがRakuはうるう秒をサポートしていると言っていたが、それは部分的には私のせいかもしれない
Perl 5で最も人気のある日付/時刻ライブラリ
DateTime.pmがうるう秒をサポートしており、私がDateTime.pmを作ったときにそのサポートを実装した振り返ると、ほぼ確実に失敗だった。うるう秒に関心のある人はほとんどおらず、「60秒足すのと1分足すのは、なぜたまに違うのか?」のような妙な混乱を生むだけだ
特に
second => 60が有効かどうかを検証しようとしたため、コードははるかに複雑になった。コンストラクタは時刻の構成要素と任意のタイムゾーンを受け取るので、うるう秒テーブルを確認するにはUTCへ変換しなければならず、その変換自体が歴史的理由からうるう秒を含む値と絡み合うことになるごく小さな利益のために巨大な混乱になってしまったし、Rakuの標準日付/時刻ライブラリもPerl 5の
DateTime.pmから多くを借りているようなので、同じ悪い設計判断を一部受け継いでしまったのだと思う最初はどんな思考プロセスだったのか気になる。問題に没頭しすぎていたのだろうか。問題に近すぎる状態で長く集中していると、壊れる前に直す楽しさが先に立って、こういうことが起きがちだ
「Instantは原子秒とその小数部分で測られる特定の瞬間であり、どのepochにも結び付けられておらず、それを意識もしない」といった形で定義されている
今年の初め、米国の住所が与えられたときに現在の現地時刻を見つける関数を書かなければならなかった。素朴なやり方は州をタイムゾーンに静的にマッピングすることだが、それを不可能にする例外がかなりある
そのアプリケーションではコストと速度が重要だったので、米国のすべての ZIP code をUTCオフセットや夏時間遵守の有無などにマッピングしたCSVを数ドルで買った
pytzはIANAタイムゾーン名を受け取るため、結局はオフセットと夏時間の情報を特定のタイムゾーンへ手動でマッピングしなければならず、米国の海外領土や軍事基地のためにEtcタイムゾーンのような奇妙な意味論も必要だった[1] https://en.wikipedia.org/wiki/Tz_database#Area
ZIP codeでもおそらく十分かもしれないが、注意は必要だ。住所の数が多すぎないなら、より堅牢な方法は逆ジオコーディングしたうえで、タイムゾーン境界ポリゴンからIANA識別子を取得するライブラリを使うことだ
https://github.com/RomanIakovlev/timeshape は以前の同僚が管理していて、社内で行っていた作業の一部をオープンソースとして公開できた
1つか2つのシステムはデータに現地時刻を付け、残りはUTCを使っていた。夏時間を処理するアルゴリズムを作ろうとして昔の Farmers' Almanac を買ったが、ルールを読んで絶望した
暦には切り替えの名目上のルールが載っていたが、議会の介入により毎年調整されてきたし、今後もそうだろうという脚注があった。上司には「議会の将来の採決を予測するアルゴリズムが書けるなら、億万長者になってこのエンジニアの仕事は辞めている」と言った
結局、直近の既知の切り替えと将来の名目上のルールをコード化したのだと思う。まだみんながネットワーク接続される前で、コードはVAXのようなスタンドアロンのコンピュータで動いていたので、他にあまり方法がなかった
それぞれ有効性と測定品質低下の状態を持つ3つの追跡データソースを結合する作業も悪夢だったが、それでも議会の将来の行動を予測するよりは簡単だった
US/Easternのような名前付きタイムゾーンにマッピングすることだ。その後UTCオフセットが必要なら、pytzでその日付にタイムゾーンを適用してオフセットを取得すればよい名前付きタイムゾーンは固定的なので特別だ。
-05:00のようなUTCオフセットのタイムゾーンやESTのような略称は、夏時間のせいで特定の場所では時間によって固定されない誰かにタイムゾーンを尋ねるとき、オフセットや略称を選択肢として出すと、みんな混乱してしまう
緯度・経度 → タイムゾーン変換にはこのPythonライブラリを使った: https://github.com/jannikmi/timezonefinder
データソースもかなり高品質なものに見えた: https://github.com/evansiroky/timezone-boundary-builder/rele...
Etc識別子は本当に注意が必要だ。特にすべての識別子をそのままユーザーに見せようとしていたならなおさらだそのファイルには「POSIXはグリニッジの西を正とするが、多くの人はグリニッジの東を正だと期待する。たとえば
TZ='Etc/GMT+4'は略称-04を使い、UTより4時間遅い、つまりグリニッジの西を意味するが、多くの人はUTより4時間速い東側を期待する」というコメントがあるパレスチナのタイムゾーンもかなり変わっている
https://en.wikipedia.org/wiki/Time_in_the_State_of_Palestine
夏時間はあるが日付が固定されておらず、政府が毎年開始と終了の時点を発表する。時には1週間も前になってから発表されるため、さまざまな興味深い問題が起きざるを得ない
イスラエルとパレスチナの夏時間の開始日・終了日が必ずしも同じではない
1時間ではなく30分差の夏時間を「最も変わったタイムゾーン」と呼ぶには、基準が低すぎると思う
ほとんど他のものの方がもっと変わっている。Antarctica/Troll の方が明らかに奇妙に聞こえるし、モロッコやガザのタイムゾーンは既存のシステムでは表現できないほどで、少なくとも別種のルールがある。Apple の禁止リストに載った、特定の日付の前日に切り替わるタイムゾーンも、何かを壊してしまうほどには奇妙だ
うるう秒については同意する。プログラマーが知っておくべき有用な知識というより、ほとんど雑学だ。コンピュータはうるう秒をスミア処理するし、それがいつ起きたのかも分からない。完全に忘れて生きていても構わない
ただし、各国がうるう秒を無視する方式から考慮する方式へ移行したことがあり、数十年前のオーストラリアでの
GMT+xからUTC+xへの変更は、うるう秒を無視するものから含めるものへ移る転換だった。この事実がほぼ普遍的に無視されているのは、むしろ良いことなのかもしれないただ、ある大規模組織が「我々のサーバーは GPS 同期と自社開発の PCIe ルビジウム原子時計カードのおかげでミリ秒未満の時刻精度を持つ」と言いながら、同時に「うるう秒は1日かけてスミアするので、実際のサーバー時刻が ±0.5 秒ずれていても問題ない」と言うのは、いつも少し滑稽だ
[1] https://engineering.fb.com/2021/08/11/open-source/time-appli...
[2] https://engineering.fb.com/2020/03/18/production-engineering...
たとえば空が非常に曇っていれば、月がどこにあっても見ることはできない。このため、国家運営のために暦を実装する際に問題が生じる
イスラム暦を公式採用している多くの国は、特定の地点での予想可視性に基づいて事前計算した近似日付を使っている。したがってイスラム暦は実際には1つではなく、観測イスラム暦と予測暦という2つに近く、どちらも実際または予測される観測が行われる場所に依存している
モロッコやガザがどうしているのかは分からない
ただしノルウェー時間がよりによって夏時間を採用している
多くの市場はうるう秒の間は閉場しており、多くの銀行はエラーのリスクを減らすため、現地時間の変更時には今でもすべての取引を停止する
あまり気にしないアプリケーションでも、うるう秒関連のバグは驚くほど多く、CGPM がうるう秒の廃止を決定したのには十分な理由がある
https://en.wikipedia.org/wiki/Leap_second#Other_reported_sof...
タイムゾーンソフトウェアの曲芸を扱った素晴らしい記事。実にかなり柔軟だ。
すべてが自動化された有限のオフセットであるなら、夏時間ポリシーが必ずしも60分調整に合わせる必要はない。
どこかの国が1年を通して 連続的に変化するオフセット を使うことに決めることもあり得るのではないか? オフセット参照テーブルははるかに長くなるだろうが、こうすれば夏時間を「解決」できるかもしれない。少しずつ継続的に調整されるので、うるう秒のように気付かれないだろう。
アナログ時計に頼っている人たちは、毎回同じ方向に調整する必要がなくなるかもしれない。
月1回の 10分変更 は適応しやすく、ほとんど気付かれず、見逃しても1時間ずれているほど大事にはならない。
夏時間をやめればいい。個人的には恒久的な夏時間より 恒久標準時 のほうが好みだが、年に2回時計を変えるのをやめられるなら受け入れられる。
もちろん中国は、あれほど広いのにタイムゾーンが1つしかないことで有名で、国内的にも対外的にも興味深い状況を生んでいる。
TZif データ形式に明示されていない非常に重要な前提は、現地時刻から UTC 時刻へ変換するとき、可能性が最大2つしかないということだ。
多くのソフトウェアがこの前提に依存しており、たとえば
java.time.LocalDateTimeにはwithLaterOffsetAtOverlap()がある: https://docs.oracle.com/javase/8/docs/api/?java/time/LocalDa...これは、午前2:30が何を意味するのか曖昧なとき、可能な解が夏時間の前後の2つしかないと暗黙に仮定している。あるタイムゾーンが午前2時に1回後ろへ戻し、2:15にまた後ろへ戻すような形で3つ以上の解を作るなら、多くのものはそれを表現できない。
tz データベースで気に入っている点は、技術的には diff の diff だということだ。
各タイムゾーンと UTC の差が歴史的にどう変化してきたかを保存しているので、
diff^2と見なせる。しかも tz データベース自体も更新を受けるので、そのコミットは diff の diff の diff、つまりdiff^3だ。さらに進められる。変更ログがあり、その変更ログが git に保存されているので、tz 変更ログへのコミットは UTC に対する変更一覧の変更一覧の変更一覧に対する変更、すなわち
diff^4だ。ほぼすべての日付/時刻は、実際には監視中の マッチング規則の集合 だというフレーミングが重要だと思う。
マッチングがトリガーされるまでに何秒かかるかは推測できるが、実際に起こるまでは完全には確信できず、場合によってはそもそも正確には起こらないこともある。
その次の半分は、「今から X 秒後に起こるはずだ」というデルタの推測を、「そのときあなたのタイムゾーンの時計は Y を表示しているはずだ」に戻す作業だ。
どのタイムゾーンがイベントを制御しているのか、そしてどのタイムゾーンで表示されるのかを追跡し続けるのを忘れてはならない。
[1] UTC の推定値は、うるう秒のぶんだけ前後に外れる可能性がある。TAI のほうが安全だが、誰かがセシウム原子の振る舞いを変える興味深く新しい何かを発見したら話は変わるかもしれない。
[0] たとえば国が消滅してタイムゾーン自体がなくなることもあり得る。あるいは時計が 1:00 から 2:00 に飛んで、欠落した1時間のせいで 1:30〜2:00 の区間が正確には発生しないこともあり得る。