2019-07-16に更新

Goのtime.LoadLocationには外部依存性がある

Exective Summary

Goのtime.LoadLocationには外部依存性があるので、引数に空白("")、UTCLocal(time.Localにタイムゾーンを設定している場合)のいずれかではない場合(例えばAsia/Tokyo)は unknown time zoneというエラーがでる場合がある。対策としてはtime.Local = time.FixedZone("Local", 9*60*60)としてからtime.LoadLocation("Local")とすれば良い。

本編

Goではtime.LoadLocationを利用してタイムゾーンの情報を得ることができる。得たタイムゾーンの情報は、例えばtime.ParseInLocationという関数で使うことができる。一連の使い方の例として、公式ドキュメントでは以下のような例が示されている。

package main

import (
    "fmt"
    "time"
)

func main() {
    loc, _ := time.LoadLocation("Europe/Berlin")

    const longForm = "Jan 2, 2006 at 3:04pm (MST)"
    t, _ := time.ParseInLocation(longForm, "Jul 9, 2012 at 5:02am (CEST)", loc)
    fmt.Println(t)

    // Note: without explicit zone, returns time in given location.
    const shortForm = "2006-Jan-02T03"
    t, _ = time.ParseInLocation(shortForm, "2012-Jul-09T01", loc)
    fmt.Println(t)

}

例ではEurope/Berlinがタイムゾーンとして設定されているが、これは実行環境にあるタイムゾーンの設定ファイルなどを参照するために使われている。よって、Alpineのように何も環境下でtime.ParseInLocationを実行して迂闊にタイムゾーンの名前を渡すと、 unknown time zoneというエラーが発生してアプリケーションが実行できなくなる。そんな場合はtime.Local = time.FixedZone("Local", 9*60*60)のように予めtime.Localにタイムゾーンの設定情報を入れておいてtime.LoadLocation("Local")とすることでエラーを防ぎ、かつアプリケーションから外部依存性を取り除くことが出来る。

// https://play.golang.org/p/lRiZxwT1u-U
package main

import (
    "fmt"
    "time"
)

func main() {
    time.Local = time.FixedZone("Local", 9*60*60)
    jst, _ := time.LoadLocation("Local")

    layout := "2006-01-02T15:04:05"
    t, _ := time.ParseInLocation(layout, "2019-07-15T20:21:22", jst)
    fmt.Println(t)  // Print "2019-07-15 20:21:22 +0900 Local"
}

もう少し踏み込んで確認したい場合はソースコードを読んでみると良い。

おしまい。


shige

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント