2025/07/25 18:05 Monotonic and Wall Clock Time in the Go Time Package

やっほー、ロボ子!今日のITニュース、なかなか興味深いものがあるのじゃ。

博士、こんにちは。今日はどんな話題ですか?

今日はGoの`time`パッケージについて!壁時計時間と単調時計時間の違い、知っておるか?

壁時計時間と単調時計時間ですか?なんとなくは分かりますが、詳しく教えてください。

壁時計時間は、私たちが普段使っている「現実世界の」時間のことじゃ。UTCとかローカル時間みたいなものだぞ。でも、NTPで同期したり、システム管理者が手動で変えたり、夏時間とかうるう秒で調整されたりするから、進んだり遅れたり、ジャンプすることがあるのじゃ。

なるほど。だから、時間間隔を正確に測るには向かないんですね。

そういうこと!そこで登場するのが単調時計時間じゃ。これは常に一定の速度で進んで、手動で調整できない時計のことじゃ。過去に戻ることがないから、時間間隔を測るのに信頼性が高いのじゃ。

Goでは、`time.Time`構造体が両方の時間を持っているんですね。

`time.Time`は壁時計時間と、オプションで単調時計の読み取り値を保持しておる。単調時計の値は`ext`フィールドに内部的に格納されていて、直接アクセスはできないのがミソじゃ。

`time.Now()`で作られた`time.Time`だけが単調時計の情報を持つ、と。

そう!そして、よくある間違いとして、`time.Time`の値の比較に`==`演算子を使うと、単調時計の情報が消えたり、`time.Location`ポインタの違いで誤った結果が出たりするのじゃ。

`Equal`メソッドを使うべきなんですね。

その通り!`time.Date`とか`time.Unix`、`time.Parse`で作られた`time.Time`は、壁時計時間しか持ってないから注意が必要じゃ。

パフォーマンスのヒントもあるんですね。高頻度で壁時計時間を取得する必要がある場合、`time.Now()`の代わりに、単調時計を持つ`time.Time`値を使って計算すると良い、と。

ただし、時計の調整は考慮されないから、そこは注意じゃぞ!

`time.NewTicker`や`time.Sleep`などのタイマーは、デフォルトで単調時間を使うから、壁時計のジャンプに影響されにくいんですね。

そうそう。でも、cronジョブとかログローテーションみたいに、壁時計に基づいてスケジュールする必要がある場合は、注意が必要じゃ。

`time.Time`構造体の内部構造も変わったんですね。Go 1.9から、壁時計時間と単調時計時間を格納するために。

単調時計がない場合は、`ext`が壁時計の秒数を全部格納できる。単調時計がある場合は、`ext`が単調時計の秒数を格納して、壁時計の秒数は`wall`に移動するのじゃ。

壁時計の範囲が1885年から2157年の範囲外になると、単調時計の情報が消えるんですね。

そういうこと!なかなか奥が深いじゃろ?

勉強になりました!ありがとうございます、博士。

どういたしまして!ところでロボ子、時間が止まると嬉しいのは誰じゃ?

え?誰でしょう…?

それは、時をかける少女!…って、ベタすぎたかのじゃ?
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
