Golangのタイムゾーン処理をscratchコンテナで動かす

2024/01/29に公開

プログラミングでタイムゾーンを扱う処理を実装する機会は多いです。

しかし、Golangでは、タイムゾーンを使った実装がscratchコンテナ等で動かないケースが存在します。

scratchコンテナ等で動かないコード

scratchコンテナで動かないコードは以下のようなコードです。

処理内容は、引数の日付文字列をjstに変換してtimeとerrorの戻り値を返しています。

func convertToJST(dateStr *string) (*time.Time, error) {
	// レイアウトの指定
	layout := "2006/01/02"

	// 文字列から time.Time への変換
	t, err := time.Parse(layout, *dateStr)
	if err != nil {
		return nil, err
	}

	// タイムゾーンの設定
	jst, err := time.LoadLocation("Asia/Tokyo")
	if err != nil {
		return nil, err
	}

	// タイムゾーンを適用
	t = t.In(jst)

	return &t, nil
}

このコードは

windows, mac, ubuntu上では動作しますが、dockerのscratchコンテナでは動きません。

理由は

LoadLocationで利用するタイムゾーンのファイルがscratchコンテナ内にないから

です。

なので

apk tzdata

で解決する問題ではありますが、コンテナ容量はなるべく軽くしたいので、上記のコマンドは実行したくありません。

scratchコンテナ等で動くコード

scratchコンテナでコードで動かすには、以下のように実装を変更します。

func convertToJST(dateStr *string) (*time.Time, error) {
	// レイアウトの指定
	layout := "2006/01/02"

        // jstタイムゾーンをFixedZoneで作成
        jst := time.FixedZone("Asia/Tokyo", 9*60*60)

	// 文字列から time.Time への変換
	jstTime, err := time.ParseInLocation(layout, *dateStr, jst)
	if err != nil {
		return nil, err
	}

	return &t, nil
}

これだとタイムゾーンファイルが不要で、FixedZoneで作成したタイムゾーンでtimeオブジェクトを生成できます。

生成AIに命令する場合

chatGPTを使う場合も、デフォルトだとLoadLocationのコードを出力してしまうので、細かく上記の指示をする必要があります。

あなたはGOのシニアプログラマーです。

文字列のポインタで受け取った2022/11/11という日付データをjstに変換し、*time.Time, errorの戻り値で実装してください。
この時、jstタイムゾーンをFixedZoneで作成せよ

このように命令すると以下のようなコードが出力されます。

import (
	"fmt"
	"time"
)

func convertToJST(dateStr *string) (*time.Time, error) {
	// レイアウトの指定
	layout := "2006/01/02"

	// 文字列から time.Time への変換
	t, err := time.Parse(layout, *dateStr)
	if err != nil {
		return nil, err
	}

	// FixedZoneでAsia/Tokyoのタイムゾーンを作成
	jst := time.FixedZone("Asia/Tokyo", 9*60*60) // UTC+9

	// タイムゾーンを適用
	t = t.In(jst)

	return &t, nil
}

time.FixedZoneを使用してUTCからのオフセットを指定してAsia/Tokyoタイムゾーンを作成し、その後、time.Inメソッドを使用してこのタイムゾーンを適用しています。

完璧ですね。

まとめ

Goでタイムゾーン処理を実装する時は、プログラミングが動作する環境まで意識しましょう。

以上

Discussion