Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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言語のtimeパッケージに関するドキュメントやソースコード(internalToUnix の定義など)
  • Windows APIの Systemtime および Timezoneinformation に関するMicrosoftのドキュメント
  • Unix時間の概念に関する一般的な情報