Go言語の忘れがちなtime fomatの話

2016-12-06

この記事はGo Advent Calendar 2016 - Qiitaの7日目の記事です。 apexの話でもしようと思ったのですが時間がなく別の記事を書くことにしました。

Golangを仕事で書き始めて、もう丸2年になりますが、未だに必要になると毎回ググって調べてから利用するものがあります。 その一つがtimeパッケージのフォーマットです。 GolangではいわゆるYYYYMMDDのような形式ではなく20060102といった特定の日時をベースにした文字列で表す必要があります。

123の順で振られていること、2006年なこと等なんとなくは覚えてきているのですが、確認をしないと不安で仕方なくなります。

この2年間で最低でも10回以上はgolang time formatでググり、その度にmattnさんの記事に辿り着いていました。 同じ記事を何度も見るのは自分に負けた気になるので悲しいです。

Golangの本家の実装を見るとわかるのですがtime/format.goの130行目あたりのnextStdChunkという関数でパースをしています。

これを基に判別表を作成しました。

formatabout
JanuaryMonth(long)
JanMonth(short)
1Month Number
01Month Number(zero埋め)
MondayWeekDay(long)
MonWeekDay(short)
2Day
_2Day(space埋め)
02Day(zero埋め)
15Hour(24h)
3Hour(12h)
03Hour(12h,zero埋め)
4Minute
04Minute(zero埋め)
5Second
05Second(zero埋め)
2006Year(long)
06Year(short)
PMAM or PM
pmam or pm
MSTTimeZone
Z0700ISO8601TZ
Z070000ISO8601TZ(seconds)
Z07ISO8601TZ(short)
Z07:00ISO8601TZ(colon)
Z07:00:00ISO8601TZ(seconds/colon)
-0700NumTimeZone
-070000NumTimeZone(seconds)
-07NumTimeZone(short)
-07:00NumTimeZone(colon)
-07:00:00NumTimeZone(seconds/colon)
.0, .00, .000, ...FracSecond(trailing zeros included)
.9, .99, .999, ...FracSecond(trailing zeros omitted)

またさっとYYYYMMDDで書いた時ものを置換したりしたいので、その場合のための簡単なツールを作成しました。

$ go get github.com/yudppp/gotimefmt/cmd/gotimefmt
$ gotimefmt YYYYMMDD
------------------------------------
format: 20060102
now:    20161206
------------------------------------

のようにさっとFormatと現在時間を出力されるようにしました。

timeのformatに悩まされずに済むようになりたいです。