これは「Timelab Advent Calendar 2023」の7日目の記事です。 https://adventar.org/calendars/9244
はじめに
今年初の投稿です。
今回、業務委託で一緒にお仕事をさせていただいている、Timelab さんのアドベントカレンダーに参加することになりました!
テーマは『時間』とのことなので、コンピュータにおける『時間』(システム時間)について、簡単に整理したいと思います。
システム時間
システム時間は、コンピュータの OS が提供する現在時刻のことを指します。
この時間は Epoch(基準)からの経過時間として表現され、プログラムやシステムはこの時間を用いて様々なイベントの順序やタイムスタンプを管理しています。
MacOS や Linux などの Unix系OS では、Epoch として Unix time を採用しているので、1970年1月1日 00:00:00 UTC 時点からの秒数で時間を表現します。
このことは、MacOS の場合ターミナル上でdate
コマンドを実行すると確認できます。
$ date
date # 現在時刻を表示
> 2023年 12月 3日 日曜日 18時09分28秒 JST
$ date +%s # 現在時刻のシステム時間を表示
> 1701594597
$ date -r 0 # Unix timeを表示
> 1970年 1月 1日 木曜日 09時00分00秒 JST
余談ですが、たまにニュースなどで目にする『2038年問題』は、この Unix time と 32bit符号付き整数(int32)に起因する問題であったりします。
どのように時を刻んでいるか
システム時間は、OS が管理するシステムクロックによって時を刻んでいます。
システムクロックとは、CPU が複数の電子回路同士が信号を送受信するタイミングを揃えるために用いられるクロック信号を指します。
クロック信号は定期的に振動し、OS はそのサイクルに同期してシステム時間を進めています。
コンピュータのクロック信号は、一般的に数GHzと非常に高周波数なので、精度高く時間を進めることができます。
シャットダウン時にも時を刻む
システムクロックは OS 上で動作するので、コンピュータの電源を切る(OS をシャットダウンする)と、システム時間は停止してしまいます。
したがって、コンピュータを再起動すると、終了した時間からまた時を刻み続けて、実際の時間とズレが生じてしまいます。
この問題を解決するために、コンピュータにはRTC(Real Time Clock)というハードウェアが組み込まれています。
RTCは、シャットダウンする前にシステムクロックから渡された時間情報を用いて、電源がオフの間中時を刻み続けます。
逆に、電源がオンになったときには、OSが起動したタイミングでシステムクロックに時間情報を渡して、時を刻む作業をシステムクロックに任せます。
多くの RTC は、マザーボード上にある専用の電池によって動作するので、長年放置していると電池切れによって時間の挙動が不安定になります。
あるあるかと思うのですが、長い間使っていないコンピュータやデバイスを久々に起動したら、時間がリセットされている現象はこれに起因しています。
ちなみに Linux だとhwclock
コマンドを実行することで、RTC が管理している時刻の読み出しができるのですが、MacOS だとデフォルトで入っていないようです。
$ hwclock --show
時間のズレへの対応
システムクロックは非常に高精度ですが、RTC はそれほど精度が高くありません。
そのため、OS のシャットダウンを繰り返しているとどうしても実際の時間とのズレが生じます。
この問題を解消するために、OS は定期的にバックグラウンドで、NTP を用いて時刻を正確に合わせています。
NTP は RFC 5905 で規定されている、ネットワーク上で時計を同期させるためのプロトコルです。
OS はまず NTP を利用して、ネットワーク上の NTP サーバから時間情報を取得します。
そして、この情報をもとにシステムクロックに反映させ、システム時間を正確に調整することで、ネットワーク上の時間と同期を行います。
MacOS では、sntp
コマンドか、システム設定 > 一般 > 日付と時刻から、NTP サーバの設定を行うことができます。
sudo sntp -sS ntp.nict.jp
デフォルトでは、Apple の NTP サーバ(time.apple.com.)に接続するようになっているはずです。
所感
少々マニアック、かつ他の方が話す内容とは全く方向性が異なりますが、最後まで読んでいただきありがとうございます。
普段触っている場所とは全くレイヤが異なるので、まとめるのにも少し苦労しましたが、文章に落とし込むことでだいぶ腑に落ちました。
もし間違っている箇所などあれば、Twitter をやっておりますので、そちらに DM などいただけますと嬉しいです!