[インデックス 10560] ファイルの概要
このコミットは、Go言語の time
パッケージにおけるWindowsビルドの問題を修正するものです。具体的には、src/pkg/time/zoneinfo_windows.go
ファイル内の pseudoUnix
関数において、Unix時間への変換ロジックに internalToUnix
というオフセットを加えることで、Windows環境での時刻計算の正確性を確保しています。
コミット
commit 68e30a9765ca2fc596af32e75935b33c27c3d59b
Author: Alex Brainman <alex.brainman@gmail.com>
Date: Thu Dec 1 15:26:28 2011 +1100
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/68e30a9765ca2fc596af32e75935b33c27c3d59b
元コミット内容
time: fix windows build
R=rsc
CC=golang-dev
https://golang.org/cl/5440071
変更の背景
この変更の背景には、Go言語の time
パッケージがWindows環境で正しく動作しない、あるいはビルドできない問題があったことが示唆されています。特に、zoneinfo_windows.go
というファイル名から、Windows固有のタイムゾーン情報や時刻計算に関する問題であったと推測されます。Go言語はクロスプラットフォーム対応を目指しているため、各OSのシステムコールや時刻管理の差異を吸収する必要があります。このコミットは、WindowsにおけるUnix時間への変換ロジックに不整合があったため、それを修正する必要があったと考えられます。
前提知識の解説
このコミットを理解するためには、以下の概念が重要です。
- Unix時間 (Epoch Time): 1970年1月1日00:00:00 UTC(協定世界時)からの経過秒数で時間を表現する方法です。多くのシステムで内部的に時刻を扱う際に用いられます。
syscall.Systemtime
: Windows APIで時間を表現するために使用される構造体です。年、月、日、時、分、秒、ミリ秒などの要素で構成されます。Unix時間とは異なる表現形式です。syscall.Timezoneinformation
: Windows APIでタイムゾーン情報を取得するために使用される構造体です。標準時と夏時間のオフセット、タイムゾーン名などが含まれます。secondsPerDay
: 1日あたりの秒数を表す定数です。時刻計算において、日数を秒数に変換する際に使用されます。internalToUnix
: Go言語のtime
パッケージ内部で使用される定数で、Goの内部時刻表現(GoのEpochは西暦1年1月1日)とUnix Epoch(1970年1月1日)との間の秒数オフセットを表します。Goの内部時刻は、Unix時間とは異なる基準点を持っているため、Unix時間との相互変換にはこのオフセットが必要になります。具体的には、Goの内部時刻からUnix時間に変換する際にこのオフセットを加算(または減算)します。
技術的詳細
このコミットの技術的詳細は、Windowsのシステム時刻表現とUnix時間の間の変換におけるオフセットの適用にあります。
pseudoUnix
関数は、Windowsの syscall.Systemtime
構造体から擬似的なUnix時間を計算することを目的としています。Windowsの時刻表現は、Unix時間とは異なる基準点と構造を持っています。Go言語の time
パッケージは、内部的にGo独自のEpoch(西暦1年1月1日)を基準とした時刻表現を使用しています。
これまでの実装では、t.sec + int64(day-1)*secondsPerDay
という計算で、Goの内部時刻表現から日数を考慮した秒数を算出していました。しかし、この計算だけでは、Goの内部時刻の基準点とUnix時間の基準点(1970年1月1日)との間の差が考慮されていませんでした。
+ internalToUnix
を追加することで、この基準点のずれを補正しています。internalToUnix
は、Goの内部時刻のEpochからUnix Epochまでの秒数オフセットを表す定数です。このオフセットを加えることで、pseudoUnix
関数が返す値が、Windowsのシステム時刻を正しくUnix時間に変換したものとなるように修正されました。
この修正により、Windows環境でGoの time
パッケージが時刻を正確に扱い、特にタイムゾーン情報や日付の計算において、期待されるUnix時間との整合性が保たれるようになりました。これは、GoアプリケーションがWindows上で時刻関連の処理を行う際のバグを防ぎ、クロスプラットフォーム互換性を向上させる上で非常に重要です。
コアとなるコードの変更箇所
--- a/src/pkg/time/zoneinfo_windows.go
+++ b/src/pkg/time/zoneinfo_windows.go
@@ -62,7 +62,7 @@ func pseudoUnix(year int, d *syscall.Systemtime) int64 {
day -= 7
}
}\n-\treturn t.sec + int64(day-1)*secondsPerDay
+\treturn t.sec + int64(day-1)*secondsPerDay + internalToUnix
}\n
func initLocalFromTZI(i *syscall.Timezoneinformation) {
コアとなるコードの解説
変更されたのは src/pkg/time/zoneinfo_windows.go
ファイル内の pseudoUnix
関数の一行です。
元のコード:
return t.sec + int64(day-1)*secondsPerDay
修正後のコード:
return t.sec + int64(day-1)*secondsPerDay + internalToUnix
この変更は、pseudoUnix
関数が計算する擬似的なUnix時間に、internalToUnix
という定数を加算するというものです。
t.sec
: おそらく、syscall.Systemtime
から変換された、Goの内部時刻表現における秒数(またはそれに近い値)です。int64(day-1)*secondsPerDay
: 日数(day
)を秒数に変換し、現在の日の開始からのオフセットを計算しています。internalToUnix
: この定数は、Goの内部時刻の基準点(西暦1年1月1日)とUnix時間の基準点(1970年1月1日)との間の秒数差を補正するためのオフセットです。
この一行の追加により、pseudoUnix
関数が返す値が、Windowsのシステム時刻をGoの内部時刻表現を経由して、最終的に正しいUnix時間として解釈できるようになります。これにより、Windows環境での時刻計算の正確性が向上し、ビルド時の問題や実行時の時刻のずれが解消されます。
関連リンク
- Go Change List: https://golang.org/cl/5440071
参考にした情報源リンク
- Go言語のtimeパッケージに関するドキュメントやソースコード(
internalToUnix
の定義など) - Windows APIの
Systemtime
およびTimezoneinformation
に関するMicrosoftのドキュメント - Unix時間の概念に関する一般的な情報