スマートフォンやパソコン、クラウドサーバーなど、身の回りのコンピューターは正確に時を刻んでいるように見えます。しかし、ネットワークから切り離して放置すると、どんなコンピューターの時計も確実にずれていきます。数日で数秒、数か月で数分の狂いが生じることも珍しくありません。
超高速な計算をこなす電子機器が、なぜ「正確に1秒を測り続ける」という一見単純な動作でつまずいてしまうのでしょうか。
理由は大きく2つあります。1つは、内部で時を刻むハードウェア発振器(水晶振動子)に、製造誤差や温度変化による周波数偏差(ppm単位)が存在することです。もう1つは、ネットワーク経由で時刻を補正しようとしても、通信遅延の揺らぎや経路の非対称性によって不確かさが残るためです。
この記事では、発振器がずれる物理的理由から、NTP同期の原理的限界、OSの時刻管理、分散システムで因果関係を守る工夫までを分かりやすく解説します。
1. コンピューター内部で時を刻む仕組みと周波数のずれ
コンピューターの時計の仕組みを理解するには、まず「電源が切れているとき」と「OSが起動しているとき」で、使われている機構が異なる点を知る必要があります。
2つの時計:ハードウェアRTCとOSのタイマー
コンピューター内部には、役割の異なる主に2種類の時計が存在します。
- ハードウェアRTC(リアルタイムクロック)
マザーボード上に配置された独立した電子回路です。パソコンの主電源を切っても、ボタン電池や小型バッテリーから微弱な電力供給を受け、現在の日時を保持し続けます。消費電力を抑えるため、腕時計と同様の「32.768 kHz」の水晶振動子が広く使われます。
- OS稼働中の時刻管理機構(高分解能タイマー)
OS起動時、コンピューターはRTCから日時を一度読み取って初期値とします。しかし、RTCの読み出しはCPUにとって非常に低速なため、起動中に何度もRTCを参照することはありません。稼働中は、CPUのタイムスタンプカウンタ(TSC)やACPIタイマー、HPET(High Precision Event Timer)といった高分解能タイマーを用い、微小なパルスを数えて時刻を更新します。
水晶振動子が時を刻む原理と「ppm」の考え方
これらの時計の基準となるのが「水晶振動子(クォーツ)」です。水晶に電圧を加えると規則正しく振動する「圧電効果」を利用し、例えば32.768 kHzの振動子であれば、32,768回の振動をカウントするごとに「1秒経過」と判定します。
しかし、工業製品である以上、設計通りの周波数で完全に一定して振動し続けることはできません。公称周波数に対する実際の周波数の狂いを「周波数偏差」と呼び、ppm(parts per million:100万分の1) で表します。
ppmは「100万回の振動で何回数え間違えるか」ではなく、「公称周波数に対してどれだけの比率で振動が速い(または遅い)か」を示す相対偏差です。例えば「+20 ppm」の発振器は、公称周波数に対して 20 / 1,000,000(0.002%)速く振動します。
周波数が狂う物理的要因と発振器のトレードオフ
水晶振動子の周波数が狂う主な要因は次の3点です。
- 製造公差(個体差):微小な水晶片を加工する際、原子レベルの個体差をゼロにすることはできません。常温(25℃前後)でも数ppmから数十ppmの初期偏差が生じます。
- 温度変化:一般的な音叉型水晶振動子の周波数-温度特性は、25℃付近で最大になり、そこから温度が高くても低くても周波数が下がる、おおむね放物線状の特性を示します。CPU発熱そのものが直ちに離れたRTCの水晶を60〜80℃にするわけではありませんが、筐体内空気や基板の熱伝導により温度が変動し、周波数がずれます。
- 経年劣化(エイジング):パッケージ内部の応力変化や微小物質の吸脱着により、周波数は年月とともにわずかずつ変化します。
温度変化の影響を抑える「TCXO(温度補償水晶発振器)」や恒温槽を備える「OCXO」、さらに高精度な「原子時計」も存在します。しかし、これらは部品コスト、消費電力、設置スペースが一般的な水晶振動子より格段に大きくなります。そのため、家庭用PCやスマートフォン、標準的なサーバーでは安価で省電力な水晶振動子が選ばれており、外部からの補正なしでは時計のずれが避けられないのです。
2. シミュレーターで理解する単独時計のずれ
発振器に周波数偏差があると、時間の経過とともに時計はどれほどずれるのでしょうか。
外部同期を行わず、開始時には基準時計と同じ時刻を示し、その後も周波数偏差が一定だと仮定します。この理想化した単独動作モデルでは、基準時計との差を次の式で見積もれます。
\text{ずれ(秒)} = \text{経過時間(秒)} \times \text{周波数偏差(ppm)} \times 10^{-6}
例えば、周波数偏差が 20 ppm の発振器を考えます。1日は 24 \times 3,600 = 86,400 秒です。この式に当てはめると、次のようになります。
86,400 \times 20 \times 10^{-6} = 1.728 \text{秒}
20 ppmの偏差が一定なら、1日(86,400秒)で1.728秒、30日で約51.8秒の差になります。100 ppmなら1日で8.64秒です。これは温度変化・経年変動・NTP補正を含む実測曲線ではありません。
以下のツールで、周波数偏差(ppm)と経過時間に応じた時刻のずれを確認できます。
INTERACTIVE
実際に動かして確かめる
条件や数値を変え、本文で説明した関係を確認できます。ツールの読み方とモデルの前提条件
このツールは、周波数偏差(-100 ppm 〜 +100 ppm)と経過時間(0時間 〜 24時間)を指定し、基準時刻に対して時計が進むか(プラス)遅れるか(マイナス)を試算するシミュレーターです。
ただし、利用にあたって重要な前提条件があります。
本モデルは「一定の周波数偏差が継続し、外部同期を行わない単独動作の単純化モデル」です。現実の環境では、エアコンや昼夜の寒暖差によって周囲温度が変わり、ppmの値自体が刻々と変動します。また、後述のNTPなどにより定期的に時刻修正が行われます。そのため、現実の時計が数式通り直線的にずれ続けるわけではありません。ハードウェアの基礎特性として生じるずれの規模感を把握するための教材として参照してください。
3. ネットワーク時刻同期(NTP)の仕組みと限界
内部の発振器がずれるなら、外部の正確な時計に合わせて修正すれば解決するように思えます。現在インターネットで広く使われている時刻同期プロトコルが NTP(Network Time Protocol, RFC 5905) です。
NTPは、原子時計やGPSに直結された高精度サーバー(Stratum 1)を頂点とする階層構造を持ち、パケット交換網を通じて時刻を合わせます。しかし、ネットワーク経由の同期には原理的な限界が存在します。
NTPが時間を合わせる計算手順
クライアント(時計を合わせたい端末 A)とNTPサーバー B の間でパケットを1往復させる際、RFC 5905に基づき4つのタイムスタンプが記録されます。
- T_1:クライアント A が要求を送信した時刻(Aの時計)
- T_2:サーバー B が要求を受信した時刻(Bの時計)
- T_3:サーバー B が返信を送信した時刻(Bの時計)
- T_4:クライアント A が返信を受信した時刻(Aの時計)
クライアント A は、パケットの往復遅延 \delta とサーバーに対するオフセット \theta を次の式で求めます。
\delta = (T_4 - T_1) - (T_3 - T_2)
\theta = \frac{(T_2 - T_1) + (T_3 - T_4)}{2}
オフセット \theta の正負の解釈
RFC 5905の定義において、オフセット \theta は「サーバーBの時刻からクライアントAの時刻を引いた差(\theta = T(B) - T(A))」です。この正負の解釈は以下の通りです。
- $\theta > 0$(正の値):サーバーのほうが進んでおり、クライアントの時計が遅れています。したがって、クライアントは自分の時計を進める補正を行います。
- $\theta < 0$(負の値):クライアントのほうが進んでおり、サーバーより進みすぎています。したがって、クライアントは自分の時計を遅らせる(または進みを緩める)補正を行います。
NTPの根本的な限界:非対称遅延の壁
この計算式は、「行き(クライアント \to サーバー)と帰り(サーバー \to クライアント)の通信時間が等しい」という通信経路の対称性の仮定に依存しています。
現実のIPネットワークでは、往路と復路の遅延が同じとは限らず、混雑による変動もあります。例えば行きが30ミリ秒、帰りが10ミリ秒でも、往復時間40ミリ秒だけでは二つの片道遅延を区別できません。対称と仮定すると片道20ミリ秒ずつと見積もり、時刻差の推定に10ミリ秒の偏りが生じ得ます。
独立した外部基準がない往復通信だけから、一方向遅延の内訳を一意に知ることはできません。
NTPは複数回の通信結果から統計的にパケットを選別するフィルターアルゴリズムを備えていますが、経路の非対称性による不確かさを原理的にゼロにすることは不可能なのです。

4. OSはどうやって時計を合わせているのか
NTPでオフセット \theta が計算された後、OSはどのように時計を調整しているのでしょうか。
ステップ調整とスルー調整
OSの時計補正には「ステップ調整(step)」と「スルー調整(slew)」があります。
- ステップ調整:時計の針を瞬時に不連続にジャンプさせる方法です。PC起動直後や大きなずれがある際に使われます。RFC 5905の参照実装では、デフォルトで 0.125秒(125ミリ秒) を超えるずれがある場合にステップ調整を行う仕様になっています(閾値は設定変更可能)。
- スルー調整:時計をジャンプさせず、進むペース(周波数)を一時的にわずかに加減して、時間をかけて滑らかに正しい時刻へ追いつかせる方法です。通常運用時の微小なずれはこれで補正されます。
日常運用でステップ調整を避ける理由は、時刻が突然過去へ巻き戻ると、ログの順序が逆転したり、定期ジョブ(cron等)が予期せず重複実行されたり、データベースの整合性が崩れる危険があるためです。
2つのシステムクロック:REALTIME と MONOTONIC
OS内部で提供されるクロックを用途に応じて使い分けることは極めて重要です。
- CLOCK_REALTIME(壁時計)
人間社会の日時を表す時計です。手動操作やNTPのステップ調整により、時刻が不連続にジャンプしたり巻き戻ったりすることがあります。なお、OSのタイムゾーン設定を変更しても、内部の基準(UTCからの通算秒)が変わるわけではなく、表示上の変換ルールが変わるだけです。うるう秒の扱いも、即座に1秒戻すか、1日かけて徐々に調整するLeap Smearingを行うかなど、OSや設定によって異なります。
- CLOCK_MONOTONIC(単調増加時計)
システムの起動時などを起点とし、過去へ巻き戻らず単調に増加し続ける時計です。ここでよくある誤解は「CLOCK_MONOTONICは常に一定ペースで進み、NTPの影響を一切受けない」という認識です。手動変更やステップ調整による巻き戻りはありませんが、Linux等の一般的な実装ではNTPによる周波数調整(スルー調整)の影響を受けます。ハードウェアの周波数偏差を正すため、進むペース自体は微調整されるのです。また、サスペンド(スリープ)中の時間は原則として含まれません。
- CLOCK_MONOTONIC_RAW
NTPによるスルー調整すら受けない、ハードウェアタイマー本来の生の刻みだけを反映した時計です。発振器本来の周波数測定など特殊な用途に用いられます。
経過時間測定の落とし穴
処理時間の計測に CLOCK_REALTIME を使い「終了時刻 - 開始時刻」を計算すると、測定中に管理者操作やステップ調整等による時刻の後方変更が起きた場合、経過時間がマイナスになるトラブルを招きます。壁時計の変更に左右されない経過時間の計測には、CLOCK_MONOTONIC など目的に合う単調時計を用います。
5. 分散システムで時計のずれが引き起こす問題と解決の工夫
単一のコンピューター内であれば、CLOCK_MONOTONICによって時間の逆転を防げます。しかし、ネットワークを介して複数の機器が連携する「分散システム」では、時計のずれがさらに深刻な問題を生みます。
大原則として、「各コンピューターのローカル時計が記録したタイムスタンプの大小は、必ずしも実際の事象の因果順序を正しく表さない」 という点に注意しなければなりません。
具体例:ECサイトで起きる因果順序の逆転
注文サーバーAと在庫サーバーBが連携する例を考えます。Aの時計は正確で、Bの時計は 324ミリ秒進んでいる とします。
- 実時刻 18:00:00.150:サーバーBが在庫削減を実行。Bの時計は324ミリ秒進んでいるため、ログは 18:00:00.474 です。
- 実時刻 18:00:00.424:在庫確保を確認したサーバーAが購入完了を実行。Aの時計は正確なので、ログは 18:00:00.424 です。
現実の世界では明らかに「在庫削減(0.150秒)」が先に行われ、それを受けて「購入完了(0.424秒)」が行われています。
実際は在庫削減が先ですが、両ログを時刻だけで並べると、購入完了が在庫削減より50ミリ秒先に見えます。この例は時計のずれでログ上の因果順序を誤読し得ることを示します。時刻順だけで処理順を確定せず、イベント間の依存関係も記録する必要があります。
因果関係を保証するためのアプローチ
分散システムでは、物理時計の完全な一致に頼らず因果順序を正しく扱う工夫が発展してきました。
- Lamport論理時計
通信メッセージの送受信ごとにカウントアップする整数カウンタを用いて、事象の前後関係を整理します。ただし、Lamport論理時計が保証するのは 「事象 $a$ が事象 $b$ の原因である($a \to b$)ならば、カウンタ値は必ず $C(a) < C(b)$ になる」という一方向の関係(半順序関係)に限られます。カウンタ値が C(a) < C(b) だからといって、逆向きに「a が b の原因である」「a が物理的に先に起きた」と推論することはできません。
- Google SpannerのTrueTime API
分散データベース「Spanner」では、GPSや原子時計を用いても残るわずかな不確かさを踏まえ、現在時刻を特定の値ではなく「確実に [t_{\text{earliest}}, t_{\text{latest}}] の区間(幅 2\epsilon)にある」という不確実性区間として提供します。そしてデータ更新時、割り当て時刻が確実に過去になるまで処理を待機(コミット待機:Commit Wait)させます。時計の不確かさを区間として扱い、必要な待機を行うことで、Spannerは対象のトランザクションについて外部整合性を実現します。これは時計の誤差が消えることや、任意のアプリケーションログの順序まで自動的に保証することを意味しません。
6. よくある疑問と誤解(FAQ)
コンピューターの時計に関して、よくある疑問をまとめました。
Q1: なぜすべてのパソコンに原子時計を搭載しないのですか?
原子時計は高精度ですが、一般的なPCやスマートフォンに搭載するにはコスト、サイズ、消費電力の面で大きな制約があります。市販の超小型原子時計(CSAC)であっても部品価格は数万〜数十万円に達し、消費電力も大きくなります。数円〜数十円の小型・省電力な水晶振動子を採用し、必要に応じてネットワーク経由で補正する構成のほうが、実用性と費用対効果に優れているためです。
Q2: スマートフォンの時計が正確に見えるのはなぜですか?
スマートフォン内部の発振器も一般的な水晶振動子であるため、単独ではパソコンと同様にずれていきます。正確に見える理由は、携帯電話の基地局(GPS等で高精度に同期)やWi-Fiを通じて、バックグラウンドで頻繁に自動時刻補正が行われているためです。機内モードで通信を遮断したまま長期間放置すれば、スマートフォンでも確実にずれが蓄積します。
Q3: タイムゾーンを変更すると内部の時計自体が書き換わりますか?
内部のシステム時刻そのものが書き換わるわけではありません。主要なOSは、協定世界時(UTC)の通算秒を一元的にカウントしています。タイムゾーンの変更やサマータイムの適用は、OSがその内部時刻を画面上に地域時刻として変換・表示する際のルールが変わっているだけです。
まとめ
コンピューターの時計がずれるのは機械の故障ではなく、水晶振動子の物理特性(製造公差や温度変化による周波数偏差)と、ネットワーク通信の原理(非対称遅延やジッター)に起因する必然的な現象です。
高価な恒温槽や原子時計を載せない限りハードウェア単体のドリフトは防げず、NTPを用いてもネットワーク越しの不確かさを完全には排除できません。
現代のOSや分散システムは、単調増加時計(CLOCK_MONOTONIC)や論理時計、不確実性を織り込んだTrueTimeなどを駆使し、「時計は必ずずれるものである」という前提を受け入れた上で、破綻のない正確な動作を実現しています。
出典・参考資料
- RFC 5905: Network Time Protocol Version 4: Protocol and Algorithms Specification
- Lombardi, M. A. (2021). An Evaluation of Dependencies of Critical Infrastructure Timing Systems on the Global Positioning System (GPS). NIST Technical Note 2189
- Mills, D. L. (1991). Internet time synchronization: the Network Time Protocol. IEEE Transactions on Communications
- Corbett, J. C., et al. (2012). Spanner: Google’s Globally-Distributed Database
