エポック以降の経過時間
(aphyr.com)- POSIX time/Unix time は一般に 1970-01-01 00:00:00 以降の秒数と呼ばれるが、実際には うるう秒を無視した UTC ベースの値であり、実際の経過秒数とはずれがある
- 2024-12-25 18:51:26 UTC 時点では POSIX time は 1735152686 で、epoch 以降の実際の経過秒数は 1735152713 秒となり、27 秒の差がある
- IEEE 1003.1 は
seconds since the Epochを定義する際、1 日を常に 86,400 秒として計算し、標準の付録でも 1970 年以降に追加された 14 秒のうるう秒を互換性と計算の容易さのために無視している - UTC は太陽日との差を小さくするために うるう秒を追加し、このとき POSIX time が後ろにジャンプすることで、Linux、Qantas、Cloudflare DNS などで障害事例が起きた
- 単一コンピュータでの時間間隔の測定には
CLOCK_MONOTONICまたはCLOCK_BOOTTIMEの方が適しており、POSIX timestamp と合わせる必要があるなら leap smear や POSIX↔TAI 変換を検討すべき
POSIX time は実際の経過秒数ではない
- JavaScript
Date、GNU coreutils、Linuxtime(2)、Gotime.Unix、MySQLdatetime、RubyTime、Cassandratimestampなどは、POSIX time をしばしば Unix epoch 以降の秒数のように扱う - しかし、この表現は一般的な直感と正確には一致しない
- 例の時刻: 2024-12-25 18:51:26 UTC
- POSIX time: 1735152686
- POSIX epoch 以降の実際の経過秒数: 1735152713
- 差: 27 秒
- この差は、POSIX time が IEEE 1003.1 で UTC から導出されつつも、すべての日を厳密に 86,400 秒と仮定しているために生じる
- 標準における
seconds since the Epochの定義は、tm_sec、tm_min、tm_hour、tm_yday、tm_yearを用いて値を計算し、1970 年未満の年や負の値との関係は定義していない - 実際の 1 日の長さは常に 86,400 秒ではなく、時期によって変わる
- UTC の日付が太陽日から離れすぎないように、天文学者が定期的に うるう秒 を宣言する
- その結果、POSIX time は数年ごとに後ろへジャンプする可能性がある
- 将来的には前にジャンプすることもあり得る
- うるう秒は実際に障害につながったことがある
- Linux カーネル関連の うるう秒問題
- Qantas の Linux うるう秒バグによる遅延
- Cloudflare DNS の うるう秒の影響
標準の妥協と実務上の代替策
- IEEE 1003 付録 B は、標準の発行時点で 1970-01-01 以降に 14 回のうるう秒が追加されていたものの、計算の容易さと互換性のためにこの 14 秒を無視すると整理している
- 標準は、ほとんどのシステムの “time” 値は増え続けるとみなし、うるう秒の間もこの値が増加すべきだという立場を取る
- 同時に、ほとんどのシステムはうるう秒を追跡していないか、標準時基準に同期していない可能性があることも前提としている
- そのため
seconds since the Epochが、参照時刻と epoch の間の正確な秒数を必ず表すことまでは要求していない - アプリケーションがこの値を epoch 以降の秒数のように扱えれば十分であり、必要な精度はシステムベンダーと管理者が調整すべきという立場である
- 分散アプリケーションでは timestamp でイベントを同期するため、一貫した解釈が重要になることがある
- うるう秒の累積は予測できない
- epoch 以降のうるう秒の数は増える可能性がある
- 標準は、天文学的には短い期間におけるアプリケーション間の時間同期をより重視している
- 実際のシステムは時間が多少ずれてもたいてい動作するが、うるう秒はまれであり、「epoch 以降の秒数」という 線形な直感が強いため、未発見のバグが蓄積する可能性がある
- 状況別の代替策は次のとおり
- 1 台のコンピュータで 2 つのイベント間の duration だけを計算するなら
CLOCK_MONOTONIC、さらに言えばCLOCK_BOOTTIMEを使う - POSIX time を前提とする他のシステムと timestamp をやり取りする必要がないなら TAI, GPS, LORAN を使う
- POSIX timestamp 系のシステムとおおむね合わせる必要があるなら、leap smear でうるう秒をより長い時間区間に分散させる
- qntm の t-a-i のようなライブラリで POSIX と TAI の間の変換が可能
- 1 台のコンピュータで 2 つのイベント間の duration だけを計算するなら
- うるう秒を廃止しようとする取り組み が進んでおり、2035 年までに 実現されることが期待されている
1 日 86,400 秒という仮定に依存するあらゆるものに変換テーブルを入れる追加作業が必要になる- 2035 年以降の時刻については、「2 つの時刻の間に何秒あるのか」といった問いがはるかに単純になる可能性がある
1件のコメント
Hacker Newsの意見
Vernor Vingeの2000年のSF小説 A Deepness in the Sky をちょうど読み終えたところだが、epoch以後の秒数(seconds since the epoch)への思いがけない言及が出てくる見事な一節がある
「Tradersの時間計測方式を見よ…」で始まり、Qeng Hoが人類がOld Earthの月に初めて足を踏み入れた瞬間から秒単位で数えているが、さらに詳しく見ると開始時点は実際には約1,500万秒後、初期の人類のコンピュータOSのひとつにおける0秒だった、という描写になっている
「宇宙の中のコンピュータサイエンス」をもっと読みたいならBobiverseシリーズを、「人間 + シミュレーション + コンピュータ」の探究をもっと読みたいならPermutation Cityを勧める
時間計測について読むたびに、必ず何か新しく学ぶことがある。Unix時間はロールオーバーだけ考えれば時間を追跡する最も単純な方式だと思っていたし、うるう秒 は知っていたが、これにも適用されるとは考えたことがなかった
「UTC, GPS, LORAN and TAI」のリンクも読んだが、GPS時間がうるう秒を反映しない点は興味深い対比だ
「2035年までにうるう秒をなくそうという動きが進んでいる」という計画はあまり気に入らない
UTCの本質は、TAIから整数秒だけずれていて平均太陽時(MST)に近いことにある。もうMSTを追跡しないのなら、単にTAIへ移行すべきだ
UTCをMSTから離れていくままにすると、過去のうるう秒は引き続き処理しなければならないのに、そのうるう秒がもはや目的を持たない 中途半端な状態 になる
ただ、この提案が完全に無意味というわけではない。既存の UTC時刻管理 は変えず、2035年以降の2つのタイムスタンプの差が正確な物理秒数になるようにする、という目的はある
それでもMSTはすでにUTCの機能なのだから、それを取り除くのはおかしく見える
しかし現実には多くのシステムが誤った選択をしており、特にUNIXが最大の原因だ。その選択が無数のシステムや規格に深く組み込まれているため、「単にTAIへ移行する」のは事実上不可能だ
だからUTCを「新しいTAI」として再解釈するほうが容易だ。いつか昔のUTCが別の名前で再登場しても驚かないと思う
ほとんど、あるいはすべての国で民間の時刻はUTCを基準にしている。少しだけより純粋だという理由で、世界中の時計を30秒ほど後ろへ戻すことはない
GPS時間にもTAIとのオフセットがあるが、誰もそれほど気にしていない。Unix epochも同じで、結果が一貫していればそれで十分だ
Leap_Secondというファイルを作ればいい。毎月このファイルがあるか確認し、あれば削除してからLeap_Secondsファイルの値に1を足し、LSSEというバックアップを作ればよい「You are not expected to understand this.」両方のシステムを維持するやり方だ。望むならハッシュやルックアップテーブルでも作れる
現代的な UTC epoch が1972年1月1日である点も重要だ。それ以前のUTCはTAIと異なる秒の長さを使っていた
1971年末には中間段階として、正確に0.107758 TAI秒の最後の不規則なジャンプがあり、1958年から1971年までのUTCまたはTAIの小さな時間ステップと周波数調整の合計がちょうど10秒になるよう調整された。したがって1972年1月1日 00:00:00 UTCは、正確には1972年1月1日 00:00:10 TAIだった。その後は整数秒の差になった
同時にUTCのティック速度はTAIと完全に同じになり、UTCはUT2ではなくUT1を追跡し始めた。したがって1970年と1971年のUnix時間は、その時期の実際のUTC時刻とは一致しない
https://en.wikipedia.org/wiki/Coordinated_Universal_Time#His...
https://en.wikipedia.org/wiki/Unix_time#UTC_basis
出生証明書の時刻が秒単位で正確だと仮定してもそうだ。その人の生涯の一部では、「1秒の長さ」と見なされていた値が、今私たちが普通に考える1秒と比べてかなり異なっていたからだ
ここでいう秒とは、セシウム133原子の摂動のない基底状態における超微細遷移周波数 9,192,631,770/s を基準とする秒を意味する
最近ある取引所向けのコードを書いたのだが、そのシステムは VAX、正確には OpenVMS 上で動いており、epoch は 1858年11月17日だった。
キャリアの中で Unix 以外の epoch を見たのは初めてで、幸い使っていたコードでは Unix epoch に抽象化されていた。
https://www.slac.stanford.edu/~rkj/crazytime.txt
1950年代のコンピュータのメモリにこれらの日付を収めるため、暦を240万日ぶんオフセットし、その結果 0日目が 1858年11月17日になった。
https://www.joelonsoftware.com/2006/06/16/my-first-billg-rev...
macOS/Swift Foundation API
NSDate.timeIntervalSinceReferenceDateは 2001年1月1日を epoch として使う。Wikipedia にも便利な一覧がある: https://en.wikipedia.org/wiki/Epoch_(computing)#Notable_epoc...
ある時点は POSIX タイムスタンプ では表現できず、また一部の POSIX タイムスタンプは実際の時刻に対応しなくなる。
それは ISO 8601 に年が存在しない時点があると言うのに近い。すべての時点には年があるが、ある年は他の年より長いだけだ。
https://time.is/UTC を座って眺めていれば、時間は単調に増加し、ときどきある1秒がほんの少し長くなるだけだと分かる。たとえば 24時間の中で 0.001% ほど長くなる、といった程度だ。
データベースに日付を保存するときは、常に Unix epoch 時間 で保存し、日付フィールドにはタイムゾーン情報を記録しない。タイムゾーンを知る必要がある要件があれば、別に保存する。
その代わり、タイムスタンプを TAI 形式で保存し、必要なときに UTC に変換する関数を使って、地球に関する補正が必要なときに対応できるようにすべきなのだろうか。
タイムゾーンが地雷原だというのは分かっているが、それも時間の経過とともに境界が変わる人間の構築物だ。絶対時間に固定しておいて、必要なときに望むローカル時刻形式でレンダリングすべきな気がする。
うるう秒の調整はタイムゾーン変換と同じ場所で行われるべきだ。残念ながら Unix が誤ったものを標準化してしまい、移行は難しい。
したがって、どのみちすべての時計は UTC に合わせられている。保存時に UTC から TAI に変換し、読み出し時にまた戻すことになるので、混乱するだけだろう。
通常、データベースは保存されたタイムスタンプに対するタイムゾーンの概念を持たないか(SQL Server)、あるいは「タイムゾーン対応」タイムスタンプ型を提供していても入力を UTC に変換して元のタイムゾーンを捨てる(MySQL、Postgres)。
知る限り、Oracle だけが
with time zone型でローカルではないタイムゾーンを実際に往復保持できる。計算によっては 1秒の差が大きな問題になる。最も広く使われている形式ではないものを採用するときは慎重であるべきで、標準から外れるだけの正当な理由が必要だ。単に違うというだけでもコストは大きくなりうる。
この記事のせいでクリスマスが台無しになった気分だ。神聖なものは何もないのか? 秒とは epoch 以降の秒であるべきだ。
太陽日から少しずれることを、なぜ気にする必要があるのか分からない。epoch 以降の秒を日付表現に変換するコンバータが補正を担当すればよいのではないか?
すべてのソフトウェアにうるう秒の導入をハードコードさせ、スミアリングを処理させ、新しいうるう秒が導入されるたびに1か月以内の更新を要求するようなことはしたくない。
これまでも気にしたり考えたりする必要はなかったし、これからもその必要はない。正しいやり方で処理されている。
うるう秒は赤道に取り付けた 大型ロケット で置き換えるべきだ。時計を調整するのではなく、惑星を調整しよう。
イスラム教の伝承における終末とダッジャール(Dajjal)に関する話にも、こうしたことが実際に起こるかのような一節がある。「ダッジャールの最初の日は1年のようで、二日目は1か月のようで、三日目は1週間のようになる」とされ、多くの人はこれを文字どおり、すなわち地球の自転が実際に遅くなり、最終的には向きが反転して太陽が西から昇るような宇宙的出来事として受け取っている。それが人類終末の最後の兆候だ。
うるう秒のせいで epoch が
date +%sが暗示するより29秒古いとしても、だから何なのかという気がする現在時刻を表すある数値 N にみんなが合意しているという事実のほうが、はるかに重要だ。仮想的な -29 秒が現実世界に影響するわけではない。30年前の目標に対してミサイル照準ルーチンを走らせるわけでもないだろう
うるう秒の廃止には賛成だが、時刻の不一致を強調することが有用だとは思わない。厳密には正しい話だとしても
より重要なのは未来への影響だ。過去のタイムスタンプが単純な「現在 - N秒」計算と数秒ずれること自体は、たいてい興味深い事実に近いが、将来のある時点で全ての時計がまた1秒ずれなければならないかもしれない、という点のほうが重要だ。これを考慮するには相当な努力が必要になる現実の事例が多い