kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Go で日付をフォーマットする場合は "2006-01-02" と書く

Go で日付をフォーマットして出力する場合,time パッケージの独特なフォーマット定義を覚える(慣れる)必要がある.最初サンプルコードで 2006-01-02 15:04:05 って日付を見たときに,まさかこれがフォーマット定義だとは思わなかった.ようするに年を出力する場合は %Y じゃなくて 2006 って書くし,月を出力する場合は %m じゃなくて 01 って書く.一度覚えてしまえば大丈夫だけど,独特だ!

n := time.Now()

fmt.Println(n)                               // 2016-03-25 19:05:54.785208 +0900 JST
fmt.Println(n.Format("2006-01-02"))          // 2016-03-25
fmt.Println(n.Format("2006-01-02 15:04:05")) // 2016-03-25 19:05:54

123456

フォーマットになっている日付には特に意味がなく,単純にアメリカ式の日付表記で数字を順番にならべたものだった.よって「1月2日 3時4分5秒 2006年(3時は午後15時を表す)」となり 123456 と並べられている.ただし,イギリス式の日付表記とは異なるし,日本式とも違うし,ある意味で混乱を招きそうな気はする.

定形フォーマットも定義されている

一部 RFC に準拠したフォーマットなどは定数として組み込まれているため,使うこともできる.詳しくは go/format.go at master · golang/go · GitHub を参照で.

n := time.Now()

fmt.Println(n.Format(time.ANSIC))            // Fri Mar 25 19:05:54 2016
fmt.Println(n.Format(time.RubyDate))         // Fri Mar 25 19:05:54 +0900 2016
fmt.Println(n.Format(time.RFC3339))          // 2016-03-25T19:05:54+09:00

leekchan/timeutil を使う

leekchan/timeutil を使うと Ruby 風に strftime でフォーマットを定義することができる.個人的には見慣れてるのもあって可読性が高く感じるし,積極的に使っていきたいなという感じ.

n := time.Now()

fmt.Println(timeutil.Strftime(&n, "%Y-%m-%d"))             // 2016-03-25
fmt.Println(timeutil.Strftime(&n, "%a %b %d %H:%M:%S %Y")) // Fri Mar 25 19:05:54 2016

github.com

jinzhu/now を使う

フォーマットとは異なるけど,ActiveSupport 風に日付の計算をする場合で,現在時刻を起点とした計算をするなら jinzhu/now を使う..BeginningOfMonth().EndOfMonth() で面倒な日付計算を一発で行ってくれる.ただし,変数名で now を使ってると名前解決ができないため,気を付ける必要がある.

n := time.Now()

fmt.Println(now.BeginningOfMonth()) // 2016-03-01 00:00:00 +0900 JST
fmt.Println(now.EndOfMonth())       // 2016-03-31 23:59:59.999999999 +0900 JST

github.com

関連記事