Skip to content

Instantly share code, notes, and snippets.

@s2kw
Last active October 22, 2024 05:35
Show Gist options
  • Save s2kw/8561e3663dff652f728a402c5f6adb31 to your computer and use it in GitHub Desktop.
Save s2kw/8561e3663dff652f728a402c5f6adb31 to your computer and use it in GitHub Desktop.

goの日付フォーマットに苦しまされた話

2001 と記述するとまともに解釈されない。

バグ状態だとこの表現 > 16010-10-16 これ

<a href="/news/2024-10-16-released/"><img src="/img/banner_release.png" alt="any">
news title!! <span class="date">|16010-10-16</span></a>

修正コード

-  {{.Title}} <span class = "date">|{{ .Date.Format "2001-01-02"}}</span>
+  {{.Title}} <span class = "date">|{{ .Date.Format "2006-01-02"}}</span>

なぜこんなことが起こったか?

正しいフォーマットは下記の通りで、間違った記述は と解釈されたため、表示が狂った。

// 正しいフォーマット
.Date.Format "2006"          // 年のみ
.Date.Format "01"            // 月のみ
.Date.Format "02"            // 日のみ
.Date.Format "15:04:05"      // 時:分:秒
.Date.Format "2006-01-02 15:04:05" // フル日時
// 誤ったフォーマット(使用してはいけない)
.Date.Format "2001"          // ❌ 年の指定が間違い
.Date.Format "2020"          // ❌ 年の指定が間違い
.Date.Format "YYYY-MM-DD"    // ❌ これはGoのフォーマットではない

実データをフォーマット扱いにするの普通に悪手にしか思えないが何かしらの思想がきっとあるに違いないのでこの後調べる。

@s2kw
Copy link
Author

s2kw commented Oct 22, 2024

Claude の回答

claude へのプロンプト

Go言語の日付フォーマットについて、実データのような形式でフォーマットを定義したのか解説がほしい。強固で一貫した思想を期待してしまう。

Go 言語の日付フォーマットの設計思想は実に興味深いものです。
一般的な日付フォーマット指定との比較から説明します:
従来の日付フォーマット(多くの言語):

CopyYYYY-MM-DD HH:mm:ss

Y: 年を表す
M: 月を表す
D: 日を表す
H: 時を表す
m: 分を表す
s: 秒を表す

問題点:

フォーマット文字が恣意的
大文字小文字の区別が必要(MM は month、mm は minute)
暗記が必要
文字の意味を理解していないと使えない

Go の日付フォーマット:

Copy2006-01-02 15:04:05 -0700 MST

設計思想:

  1. 参照による定義
    • 抽象的な文字ではなく、具体的な日時を参照として使用
    • フォーマットが実際のデータと同じ形で表現される
  2. 記憶の容易性
    • 1,2,3,4,5,6,7 と順番に増えていく数字を利用
    • 2006 年 1 月 2 日 3 時 4 分 5 秒 (7 のタイムゾーン)
  3. 自己文書化
    • フォーマット自体が例示となっている
    • コードを見るだけで出力形式が理解できる
  4. エラーの検出容易性
    • 誤った数値を使用すると明らかに異常な結果になる
    • 例:2001 を使うと 16010 のような明らかに間違った結果

実装例:

// 従来の方式
"YYYY-MM-DD"           // 抽象的で覚える必要がある
// Go の方式
"2006-01-02"          // 実データのような形で直感的

より複雑な例:

// 日付のみ
"2006-01-02"          // -> "2024-10-22"

// 時刻付き
"2006-01-02 15:04:05" // -> "2024-10-22 13:45:30"

// 月日のみ
"January 2"           // -> "October 22"
"Jan 2"              // -> "Oct 22"
"01/02"              // -> "10/22"

利点:

  1. 直感的

    • フォーマット文字列が出力例そのもの
    • 実データに近い形で定義できる
  2. 自己説明的

    • コードを見ただけでフォーマットが理解できる
    • ドキュメントを参照する必要性が低い
  3. 一貫性

    • すべての日時要素が具体的な数値で表現される
    • 特別な記号や文字を覚える必要がない
  4. エラー検出

    • 間違った使用が明白な誤りとして現れる
    • デバッグが容易

この設計は、Go 言語の「シンプルさ」「明示性」「実用性」という core values を強く反映しており、言語設計の一貫性を示す良い例となっています。
一見変わった方式に見えますが、実際の使用では非常に実用的で、学習コストも低く、エラーも起きにくい設計となっています。これは「実装の詳細を隠蔽する」のではなく、「明示的に示す」という Go 言語の思想を体現しているといえます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment