⌚
ヤバい時刻たち
時刻とコンピュータ
前提知識としてコンピュータではどのように時刻を管理しているかというと、 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
- 休日・祝日・営業日
Discussion