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

[インデックス 11760] ファイルの概要

このコミットは、Go言語の標準ライブラリtimeパッケージにおける、時刻のフォーマットとパースに関するドキュメンテーションの改善を目的としています。具体的には、time.Formatおよびtime.Parse関数で使用される「標準時刻」(参照時刻)の記述をより明確にし、ユーザーがカスタムフォーマットを定義する際の理解を深めることを意図しています。

コミット

  • コミットハッシュ: 1bfffb67d821db286f5629f32adc951418ea5697
  • Author: Rob Pike r@golang.org
  • Date: Fri Feb 10 13:52:19 2012 +1100

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/1bfffb67d821db286f5629f32adc951418ea5697

元コミット内容

    time: improve commentary about standard time and formatting/parsing
    
    Fixes #2965.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5652054

変更の背景

このコミットは、Go言語のtimeパッケージにおける時刻のフォーマットとパースに関するドキュメンテーションの曖昧さを解消するために行われました。コミットメッセージにあるFixes #2965が示すように、これはGitHub Issue #2965(time: API)に関連する修正です。

Goのtimeパッケージでは、Format関数やParse関数で時刻の書式を指定する際に、特殊な「参照時刻」を使用します。この参照時刻はMon Jan 2 15:04:05 MST 2006であり、この時刻の各要素(月、日、時、分、秒、年、タイムゾーンなど)が、書式指定文字列におけるプレースホルダーとして機能します。例えば、「月」を表すにはJanを、「日」を表すには2を使用します。

しかし、以前のドキュメンテーションでは、この参照時刻がどのように機能するのか、特にMSTGMT-0700を意味することや、それが01/02 03:04:05PM '06 -0700という形式にどのように対応するのかが十分に明確ではありませんでした。この曖昧さが、ユーザーがカスタムの時刻フォーマットを正確に定義する上での混乱を招いていた可能性があります。

このコミットは、これらの説明をより詳細かつ分かりやすくすることで、ユーザーがtimeパッケージのフォーマットおよびパース機能をより直感的に、かつ正確に利用できるようにすることを目的としています。

前提知識の解説

Go言語のtimeパッケージ

Go言語の標準ライブラリには、日付と時刻を扱うためのtimeパッケージが用意されています。このパッケージは、現在時刻の取得、特定の日時の表現、時刻の加算・減算、そして時刻のフォーマット(文字列への変換)とパース(文字列からの変換)など、幅広い機能を提供します。

time.Formattime.Parse関数

  • time.Format(layout string) string: Time型の値を指定されたlayout文字列に従ってフォーマットし、文字列として返します。
  • time.Parse(layout, value string) (Time, error): 指定されたlayout文字列に従ってvalue文字列をパースし、Time型の値として返します。

Go言語における時刻フォーマットの特殊性(参照時刻)

多くのプログラミング言語では、時刻のフォーマット文字列にYYYY-MM-DD HH:MM:SSのような記号ベースのプレースホルダー(例: Yは年、Mは月)を使用します。しかし、Go言語のtimeパッケージはこれとは異なる独自のアプローチを採用しています。

Goでは、**Mon Jan 2 15:04:05 MST 2006**という特定の「参照時刻」(reference time)をフォーマットの基準として使用します。この参照時刻の各要素が、フォーマット文字列におけるプレースホルダーとして機能します。

  • Mon: 曜日(月曜)
  • Jan: 月(1月)
  • 2: 日(2日)
  • 15: 時(15時、24時間表記)
  • 04: 分(4分)
  • 05: 秒(5秒)
  • MST: タイムゾーン(Mountain Standard Time)
  • 2006: 年(2006年)

この参照時刻は、Unixエポックタイム1136243045に対応します。また、MSTGMT-0700を意味するため、この参照時刻は01/02 03:04:05PM '06 -0700と解釈することもできます。

ユーザーがカスタムフォーマットを定義する際は、**「もしこの参照時刻が、自分が定義したいフォーマットで表示されたらどうなるか」**を考え、その結果をlayout文字列として記述します。例えば、2006-01-02と記述すれば、YYYY-MM-DD形式のフォーマットが実現されます。

このユニークなアプローチは、直感的でないと感じる人もいますが、非常に柔軟で強力なフォーマット指定を可能にします。このコミットは、この参照時刻の解釈と使用方法に関するドキュメンテーションを改善し、ユーザーの理解を助けることを目的としています。

技術的詳細

このコミットは、src/pkg/time/format.goファイル内のコメントを修正することで、timeパッケージのフォーマットおよびパース機能に関するドキュメンテーションを改善しています。主な変更点は以下の通りです。

  1. 標準時刻のGMTオフセットの明示: 以前のコメントでは、標準時刻Mon Jan 2 15:04:05 MST 2006がUnix時間1136243045であること、そしてMSTGMT-0700であることを示唆する形で(MST is GMT-0700)と記述されていました。今回の変更では、このGMT-0700という情報が、標準時刻の別の表現である01/02 03:04:05PM '06 -0700とより密接に関連付けられるように修正されました。具体的には、「MSTGMT-0700なので、標準時刻は01/02 03:04:05PM '06 -0700と考えることができる」という流れで説明が改善されています。これにより、タイムゾーンオフセットがフォーマットにどのように影響するかをより明確に理解できるようになります。

  2. カスタムフォーマット定義の例示の追加: カスタムフォーマットを定義する方法について、以前は「標準時刻があなたの方法でフォーマットされたらどうなるかを書き出す」という一般的な説明のみでした。今回の変更では、ANSIC, StampMicro, Kitchenといった既存の定数の値を例として参照するように促す文言が追加されました。これにより、ユーザーは具体的なコード例を参考にしながら、自身のカスタムフォーマットを設計できるようになります。

  3. FormatおよびParse関数のドキュメンテーションの統一と明確化: Time.Format関数とParse関数の両方において、ドキュメンテーションが更新されました。以前は「標準時刻の表現を示すことでフォーマットを定義する」という説明でしたが、変更後は「標準時刻Mon Jan 2 15:04:05 -0700 MST 2006の表現を示すことでフォーマットを定義する」と、標準時刻の完全な形式が明示的に記載されました。さらに、「フォーマットに関する詳細情報と標準時刻の定義については、ANSICのドキュメンテーションを参照してください」という文言が追加され、情報源への誘導がより明確になりました。

これらの変更は、コードの動作自体を変更するものではなく、あくまでドキュメンテーションの品質向上に焦点を当てています。しかし、Goのtimeパッケージのフォーマットメカニズムが独特であるため、このようなドキュメンテーションの改善は、ユーザーがライブラリを効果的に利用する上で非常に重要な意味を持ちます。特に、タイムゾーンの扱いやカスタムフォーマットの定義における混乱を減らすことに貢献します。

コアとなるコードの変更箇所

diff --git a/src/pkg/time/format.go b/src/pkg/time/format.go
index a5716ce699..98cf081cfc 100644
--- a/src/pkg/time/format.go
+++ b/src/pkg/time/format.go
@@ -16,11 +16,13 @@ const (
 
 // These are predefined layouts for use in Time.Format.
 // The standard time used in the layouts is:
-//	Mon Jan 2 15:04:05 MST 2006  (MST is GMT-0700)
-// which is Unix time 1136243045.
-// (Think of it as 01/02 03:04:05PM '06 -0700.)
-// To define your own format, write down what the standard
-// time would look like formatted your way.
+//	Mon Jan 2 15:04:05 MST 2006
+// which is Unix time 1136243045. Since MST is GMT-0700,
+// the standard time can be thought of as
+//	01/02 03:04:05PM '06 -0700
+// To define your own format, write down what the standard time would look
+// like formatted your way; see the values of constants like ANSIC,
+// StampMicro or Kitchen for examples.
 //
 // Within the format string, an underscore _ represents a space that may be
 // replaced by a digit if the following number (a day) has two digits; for
@@ -359,10 +361,12 @@ func (b *buffer) String() string {
 
 // Format returns a textual representation of the time value formatted
 // according to layout.  The layout defines the format by showing the
-// representation of a standard time, which is then used to describe
-// the time to be formatted.  Predefined layouts ANSIC, UnixDate,
-// RFC3339 and others describe standard representations. For more
-// information about the formats, see the documentation for ANSIC.
+// representation of the standard time,
+//	Mon Jan 2 15:04:05 -0700 MST 2006
+// which is then used to describe the time to be formatted. Predefined
+// layouts ANSIC, UnixDate, RFC3339 and others describe standard
+// representations. For more information about the formats and the
+// definition of the standard time, see the documentation for ANSIC.
 func (t Time) Format(layout string) string {
 	var (
 		year  int = -1
@@ -605,13 +609,15 @@ func skip(value, prefix string) (string, error) {\n }\n \n // Parse parses a formatted string and returns the time value it represents.\n-// The layout defines the format by showing the representation of a standard\n-// time, which is then used to describe the string to be parsed.  Predefined\n-// layouts ANSIC, UnixDate, RFC3339 and others describe standard\n-// representations.For more information about the formats, see the\n-// documentation for ANSIC.\n+// The layout defines the format by showing the representation of the\n+// standard time,\n+//	Mon Jan 2 15:04:05 -0700 MST 2006\n+// which is then used to describe the string to be parsed. Predefined layouts\n+// ANSIC, UnixDate, RFC3339 and others describe standard representations. For\n+// more information about the formats and the definition of the standard\n+// time, see the documentation for ANSIC.\n //\n-// Elements omitted from the value are assumed to be zero, or when\n+// Elements omitted from the value are assumed to be zero or, when\n // zero is impossible, one, so parsing "3:04pm" returns the time\n // corresponding to Jan 1, year 0, 15:04:00 UTC.\n // Years must be in the range 0000..9999. The day of the week is checked\n```

## コアとなるコードの解説

このコミットにおけるコードの変更は、すべて`src/pkg/time/format.go`ファイル内のコメントの修正です。

1.  **`const`ブロック内のコメント修正(行16-28)**:
    -   変更前:
        ```go
        // The standard time used in the layouts is:
        //	Mon Jan 2 15:04:05 MST 2006  (MST is GMT-0700)
        // which is Unix time 1136243045.
        // (Think of it as 01/02 03:04:05PM '06 -0700.)
        // To define your own format, write down what the standard
        // time would look like formatted your way.
        ```
    -   変更後:
        ```go
        // The standard time used in the layouts is:
        //	Mon Jan 2 15:04:05 MST 2006
        // which is Unix time 1136243045. Since MST is GMT-0700,
        // the standard time can be thought of as
        //	01/02 03:04:05PM '06 -0700
        // To define your own format, write down what the standard time would look
        // like formatted your way; see the values of constants like ANSIC,
        // StampMicro or Kitchen for examples.
        ```
    -   解説: `MST is GMT-0700`という補足が、`Since MST is GMT-0700, the standard time can be thought of as`というより自然な文脈で導入され、`01/02 03:04:05PM '06 -0700`という表現との関連性が明確になりました。また、カスタムフォーマットの定義方法について、`ANSIC`, `StampMicro`, `Kitchen`といった既存の定数を例として参照するように促す文言が追加され、ユーザーが具体的なイメージを持ちやすくなりました。

2.  **`Time.Format`関数のコメント修正(行359-368)**:
    -   変更前:
        ```go
        // Format returns a textual representation of the time value formatted
        // according to layout.  The layout defines the format by showing the
        // representation of a standard time, which is then used to describe
        // the time to be formatted.  Predefined layouts ANSIC, UnixDate,
        // RFC3339 and others describe standard representations. For more
        // information about the formats, see the documentation for ANSIC.
        ```
    -   変更後:
        ```go
        // Format returns a textual representation of the time value formatted
        // according to layout.  The layout defines the format by showing the
        // representation of the standard time,
        //	Mon Jan 2 15:04:05 -0700 MST 2006
        // which is then used to describe the time to be formatted. Predefined
        // layouts ANSIC, UnixDate, RFC3339 and others describe standard
        // representations. For more information about the formats and the
        // definition of the standard time, see the documentation for ANSIC.
        ```
    -   解説: `standard time`という抽象的な表現から、具体的な参照時刻`Mon Jan 2 15:04:05 -0700 MST 2006`が明示的に示されるようになりました。これにより、`Format`関数がどの標準時刻を基準にしているのかがより明確になりました。また、`ANSIC`のドキュメンテーションを参照することで、フォーマットと標準時刻の定義に関する詳細が得られることが強調されています。

3.  **`Parse`関数のコメント修正(行605-618)**:
    -   変更前:
        ```go
        // Parse parses a formatted string and returns the time value it represents.
        // The layout defines the format by showing the representation of a standard
        // time, which is then used to describe the string to be parsed.  Predefined
        // layouts ANSIC, UnixDate, RFC3339 and others describe standard
        // representations.For more information about the formats, see the
        // documentation for ANSIC.
        //
        // Elements omitted from the value are assumed to be zero, or when
        // zero is impossible, one, so parsing "3:04pm" returns the time
        // corresponding to Jan 1, year 0, 15:04:00 UTC.
        // Years must be in the range 0000..9999. The day of the week is checked
        ```
    -   変更後:
        ```go
        // Parse parses a formatted string and returns the time value it represents.
        // The layout defines the format by showing the representation of the
        // standard time,
        //	Mon Jan 2 15:04:05 -0700 MST 2006
        // which is then used to describe the string to be parsed. Predefined layouts
        // ANSIC, UnixDate, RFC3339 and others describe standard representations. For
        // more information about the formats and the definition of the standard
        // time, see the documentation for ANSIC.
        //
        // Elements omitted from the value are assumed to be zero or, when
        // zero is impossible, one, so parsing "3:04pm" returns the time
        // corresponding to Jan 1, year 0, 15:04:00 UTC.
        // Years must be in the range 0000..9999. The day of the week is checked
        ```
    -   解説: `Time.Format`関数と同様に、`Parse`関数においても、レイアウトが参照する標準時刻`Mon Jan 2 15:04:05 -0700 MST 2006`が明示されました。これにより、パースの挙動を理解する上での基準が明確になります。また、`Elements omitted from the value are assumed to be zero, or when`が`Elements omitted from the value are assumed to be zero or, when`に修正され、より自然な英語表現になっています。

これらのコメントの変更は、Goの`time`パッケージの最も特徴的で、時に混乱を招きやすいフォーマットメカニズムに関する説明を大幅に改善し、ユーザーエクスペリエンスを向上させるものです。

## 関連リンク

-   **Go CL**: [https://golang.org/cl/5652054](https://golang.org/cl/5652054)
-   **GitHub Issue**: [https://github.com/golang/go/issues/2965](https://github.com/golang/go/issues/2965)

## 参考にした情報源リンク

-   [https://github.com/golang/go/issues/2965](https://github.com/golang/go/issues/2965) (Go言語の`time`パッケージAPIに関するIssue)