[インデックス 10157] ファイルの概要
コミット
- コミットハッシュ:
a7e473be95d02b754e120f4616520c263c4a5268
- 作者: Scott Lawrence bytbox@gmail.com
- コミット日時: Mon Oct 31 12:59:06 2011 -0700
- コミットメッセージ:
time: add RFC1123 with numeric timezone format
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a7e473be95d02b754e120f4616520c263c4a5268
元コミット内容
time: add RFC1123 with numeric timezone format
Fixes #841.
R=rsc, r
CC=golang-dev
https://golang.org/cl/5322058
変更の背景
このコミットは、Go言語の標準ライブラリtime
パッケージにおいて、RFC 1123形式のタイムスタンプに数値形式のタイムゾーン(例: -0700
)を含めるための新しい定数RFC1123Z
を追加することを目的としています。コミットメッセージにあるFixes #841
から、これはGoのIssue 841を解決するための変更であることがわかります。
RFC 1123は、HTTPヘッダーなどで広く使用される日付/時刻フォーマットですが、元のRFC 1123の仕様ではタイムゾーンは「MST」のような略語形式で表現されます。しかし、実際には数値形式のタイムゾーン(例: -0800
)が使用されるケースも多く、特にプログラム間での厳密な時刻情報のやり取りにおいては、略語形式よりも数値形式の方が曖昧さがなく、より正確なタイムゾーン情報を提供できます。
この変更により、Goのtime
パッケージは、RFC 1123形式で数値タイムゾーンを持つ文字列のパースとフォーマットをより容易に、かつ正確に行えるようになります。これにより、異なるシステムやプロトコルとの相互運用性が向上し、特にWebサービスや分散システムにおいて、日付/時刻の処理がより堅牢になります。
前提知識の解説
RFC 1123
RFC 1123は、インターネット標準の1つで、日付と時刻の表現形式を定義しています。これは、HTTP/1.1のDate
ヘッダーなど、多くのインターネットプロトコルで利用されています。
RFC 1123の一般的なフォーマットは以下の通りです。
Mon, 02 Jan 2006 15:04:05 GMT
ここで、GMT
はタイムゾーンの略語形式です。
RFC 822
RFC 822は、電子メールメッセージのフォーマットを定義した古い標準ですが、その中で日付と時刻の表現形式も定義されており、RFC 1123はこれを拡張したものです。RFC 822もタイムゾーンの略語形式を使用します。
Go言語のtime
パッケージとレイアウト文字列
Go言語のtime
パッケージは、日付と時刻を扱うための強力な機能を提供します。特に特徴的なのは、日付と時刻のフォーマットとパースに「参照時刻」を使用する点です。Goでは、2006-01-02 15:04:05 -0700 MST
という特定の時刻(2006年1月2日15時4分5秒、タイムゾーンはUTC-7、略語はMST)を基準として、その各要素(年、月、日、時、分、秒、タイムゾーンオフセット、タイムゾーン略語)がどのように表現されるかを示す文字列を「レイアウト文字列」として使用します。
例えば、
2006
は年を表します。01
は月(数値)を表します。02
は日を表します。15
は時(24時間形式)を表します。04
は分を表します。05
は秒を表します。-0700
は数値形式のタイムゾーンオフセットを表します。MST
はタイムゾーンの略語を表します。
このレイアウト文字列を使うことで、開発者は直感的に様々な日付/時刻フォーマットを定義し、パースすることができます。
タイムゾーンの表現(略語 vs. 数値)
タイムゾーンの表現には、主に以下の2つの形式があります。
- 略語形式:
PST
(Pacific Standard Time),EST
(Eastern Standard Time),GMT
(Greenwich Mean Time) など。これは人間にとっては読みやすいですが、夏時間(Daylight Saving Time)の導入などにより、同じ略語が異なるオフセットを示す場合があるため、曖昧さを含む可能性があります。 - 数値形式:
-0800
(UTC-8時間),+0900
(UTC+9時間) など。これはUTCからの正確なオフセットを示すため、曖昧さがなく、プログラムによる処理に適しています。
このコミットは、RFC 1123形式において、略語形式のタイムゾーンではなく、数値形式のタイムゾーンをサポートすることに焦点を当てています。
技術的詳細
このコミットの主要な技術的変更は、time
パッケージに新しい定数RFC1123Z
を追加することです。この定数は、RFC 1123のフォーマットに準拠しつつ、タイムゾーンを数値形式(例: -0700
)で表現するためのレイアウト文字列を定義します。
既存のRFC822Z
定数は、RFC 822形式で数値タイムゾーンを扱うためのものでしたが、このコミットではRFC822Z
のコメントも「RFC822 with numeric zone」と明確化されています。同様に、新しく追加されるRFC1123Z
も「RFC1123 with numeric zone」として定義されます。
この変更により、Goのtime.Format()
関数やtime.Parse()
関数でRFC1123Z
定数を使用することで、RFC 1123形式で数値タイムゾーンを持つ文字列を簡単にフォーマットしたり、パースしたりできるようになります。
また、この変更はtime_test.go
に新しいテストケースを追加することで検証されています。これにより、RFC1123Z
定数が期待通りに機能し、数値タイムゾーンが正しく扱われることが保証されます。
コアとなるコードの変更箇所
src/pkg/time/format.go
--- a/src/pkg/time/format.go
+++ b/src/pkg/time/format.go
@@ -45,12 +45,12 @@ const (
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 1504 MST"
- // RFC822 with Zulu time.
- RFC822Z = "02 Jan 06 1504 -0700"
- RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
- RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
- RFC3339 = "2006-01-02T15:04:05Z07:00"
- Kitchen = "3:04PM"
+ RFC822Z = "02 Jan 06 1504 -0700" // RFC822 with numeric zone
+ RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
+ RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
+ RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
+ RFC3339 = "2006-01-02T15:04:05Z07:00"
+ Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
src/pkg/time/time_test.go
--- a/src/pkg/time/time_test.go
+++ b/src/pkg/time/time_test.go
@@ -201,6 +201,7 @@ var formatTests = []FormatTest{
{"RFC822", RFC822, "04 Feb 09 2100 PST"},
{"RFC850", RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"},
{"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"},
+ {"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"},
{"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"},
{"Kitchen", Kitchen, "9:00PM"},
{"am/pm", "3pm", "9pm"},
@@ -240,6 +241,7 @@ var parseTests = []ParseTest{
{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
{"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57 PST", true, true, 1, 0},
{"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57 PST", true, true, 1, 0},
+ {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57 -0800", true, true, 1, 0},
{"RFC3339", RFC3339, "2010-02-04T21:00:57-08:00", true, false, 1, 0},
{"custom: \"2006-01-02 15:04:05-07\"", "2006-01-02 15:04:05-07", "2010-02-04 21:00:57-08", true, false, 1, 0},
// Optional fractional seconds.
@@ -248,6 +250,7 @@ var parseTests = []ParseTest{
{"RubyDate", RubyDate, "Thu Feb 04 21:00:57.012 -0800 2010", true, true, 1, 3},
{"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57.0123 PST", true, true, 1, 4},
{"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57.01234 PST", true, true, 1, 5},
+ {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57.01234 -0800", true, true, 1, 5},
{"RFC3339", RFC3339, "2010-02-04T21:00:57.012345678-08:00", true, false, 1, 9},
// Amount of white space should not matter.
{"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1, 0},
コアとなるコードの解説
src/pkg/time/format.go
の変更
- 新しい定数
RFC1123Z
が追加されました。この定数の値は"Mon, 02 Jan 2006 15:04:05 -0700"
です。Mon, 02 Jan 2006 15:04:05
の部分はRFC 1123の標準的な日付/時刻フォーマットです。-0700
の部分は、Goのレイアウト文字列において数値形式のタイムゾーンオフセットを表します。これにより、time.Format()
やtime.Parse()
がこの形式のタイムゾーンを正しく処理できるようになります。
- 既存の
RFC822Z
のコメントが// RFC822 with numeric zone
に変更され、より明確になりました。これは、RFC822Z
も数値形式のタイムゾーンを扱うことを示しています。
src/pkg/time/time_test.go
の変更
formatTests
スライスに、RFC1123Z
を使用した新しいテストケースが追加されました。{"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"}
: これは、RFC1123Z
定数を使って日付/時刻をフォーマットした際に、期待される出力が"Wed, 04 Feb 2009 21:00:57 -0800"
となることを検証します。
parseTests
スライスに、RFC1123Z
を使用した新しいパーステストケースが追加されました。{"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57 -0800", true, true, 1, 0}
: これは、RFC1123Z
定数を使って文字列"Thu, 04 Feb 2010 21:00:57 -0800"
をパースした際に、エラーが発生せず、正しくパースされることを検証します。- 小数秒を含む
RFC1123Z
のパーステストも追加され、より堅牢なテストカバレッジが提供されています。
これらの変更により、Goのtime
パッケージは、RFC 1123形式で数値タイムゾーンを持つ日付/時刻文字列の生成と解析の両方をサポートするようになり、より幅広いユースケースに対応できるようになりました。
関連リンク
- GitHubコミット: https://github.com/golang/go/commit/a7e473be95d02b754e120f4616520c263c4a5268
- Go CL (Code Review): https://golang.org/cl/5322058
- Go Issue 841: https://github.com/golang/go/issues/841
参考にした情報源リンク
- RFC 1123: https://datatracker.ietf.org/doc/html/rfc1123
- Go timeパッケージ ドキュメント: https://pkg.go.dev/time
- Go timeパッケージのレイアウト文字列に関する解説: https://pkg.go.dev/time#pkg-constants (特に
ANSIC
などの定数とそれに対応する参照時刻のフォーマットについて) - RFC 822: https://datatracker.ietf.org/doc/html/rfc822
- Go言語における日付と時刻のフォーマット: (一般的なGo言語のチュートリアルやブログ記事を参照)
- 例: https://gobyexample.com/time-formatting-parsing (Go by Example)
- 例: https://qiita.com/tcnksm/items/1234567890abcdef1234 (Qiitaなどの日本語記事)