ヤバい時刻たち

2024/03/14に公開

時刻とコンピュータ

前提知識としてコンピュータではどのように時刻を管理しているかというと、 CPU や RAM とは別に RTC (Real Time Clock) とよばれる部品を取り付けて、必要に応じて CPU と通信している。RTC の多くは年・月・日・時・分・秒をそれぞれ BCD で保持して、 1 秒ごとに日時を更新する。機種ごとに曜日も保持していたり、年を下位2桁までしか持っていなかったりといった違いがあるが、 OS とドライバはそれらの違いを吸収して、アプリの関数呼び出しから利用できるようにしている。

アプリから呼び出す OS の関数は、特別に「システムコール」と呼ばれている。このシステムコールは、 C 言語での利用を前提としていて、 JavaScript や Python の場合はスクリプトエンジンがそれらを呼び出すことになる。あるいは Go のように C 言語と同じルールで関数呼び出しを行う特別な仕組みが用意されていたりする。そのため、どのような技術スタックを用いていても、結局は C 言語の仕様が関わってくることがある。

時刻合わせ

NTP (Network Time Protocol) という通信プロトコルで時刻をやりとりしている。この NTP サーバは、 OS の開発元や国の機関・大学などが運用していたりする。通信にかかった時刻を考慮したりして、正確な時刻が同期されるようにしている。

いわくつきの時刻たち

  • 1900 年の前後
  • 1970 年の前後
    • 1970-01-01 00:00:00 からの秒を用いる方法は UNIX 時間 と呼ばれ様々な場所で採用されている。
  • 100 年ごと (1999 → 2000, 2099 → 2100)
    • 年を下位 2 桁で保持していることがある。
    • いわゆる 2000 年問題
    • 主要なデジタル時計用 IC チップが回路的にそうなってる
  • 10 年ごと(2019→2020、2029→2030)、10日ごと、…
    • 組込みで RTC を直接操作している場合、 BCD は 4 bit ごとに0-9のみを使うが、間違えて 10〜15 が入っていたりすると繰り上げ時にバグる。
  • 2038-01-19 03:14:07
    • 1970-01-01 00:00:00 からの秒を符号付き 32 bit で表した場合の限界
  • 2106-02-07 06:28:15
    • 1970-01-01 00:00:00 からの秒を符号無し 32 bit で表した場合の限界
  • うるう年
  • 過去に存在したうるう秒
  • 未来に発生し得るうるう秒
  • 月初・月の表現
    • 1 から開始したり名前 (Jan/Feb/…) を取りやすくするために 0 から開始したりして、異なるシステム間でやり取りするときに問題になる可能性がある。
  • 月末
    • 28, 29, 30, 31
  • 週末
  • 曜日
    • ISO の規格では月曜が 0 で C の規格では日曜が 0
    • 週の開始が業界や会社の習慣によって異なったりする
  • 1 年の週は 52 週を例にすることが多いが、53, 54週のケースが存在する
  • タイムゾーン
    • サマータイム
      • 切り替えの瞬間の「毎日0:00」
  • 年・月・日の順序
    • アメリカ式: MM/dd/yy
    • イギリス式: dd/MM/yy
  • 休日・祝日・営業日
Bitkey Developers

Discussion