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

[インデックス 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つの形式があります。

  1. 略語形式: PST (Pacific Standard Time), EST (Eastern Standard Time), GMT (Greenwich Mean Time) など。これは人間にとっては読みやすいですが、夏時間(Daylight Saving Time)の導入などにより、同じ略語が異なるオフセットを示す場合があるため、曖昧さを含む可能性があります。
  2. 数値形式: -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形式で数値タイムゾーンを持つ日付/時刻文字列の生成と解析の両方をサポートするようになり、より幅広いユースケースに対応できるようになりました。

関連リンク

参考にした情報源リンク