nishiyamasuの日記

忘れやすいので、メモ。。。

Goで時間の出力形式を日本の形式にする。

Goの構造体のjson出力フォーマットを自分で決めたいことがあった。

Goでは、普通にやると次のように時間が出力される。

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Println(now)
}

// main実行結果
// 2019-01-06 22:27:31.043934843 +0900 JST m=+0.000154895

見てわかるのは、とても分かりにくいということ。 日本人なので、やはり○○年○月○日の形式で出力してほしい。

Goのtime.Time型にあるFormatメソッドにより、時間の出力形式を変更できる。

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Println(now.Format("2006年01月02日"))
}

// main実行結果
// 2019年01月06日

Goのstructにtime.Time型のフィールドがある場合を考える。

type Data struct {
    ID        int
    CreatedAt time.Time
}

CreatedAtがtime.Time型のフィールド。

このstructをjson.MarshalIndentを使って出力する。 structをjson出力すると、CreatedAtの値はデフォルトの形式で出力されてしまう。

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type Data struct {
    ID        int
    CreatedAt time.Time
}

func main() {
    data := Data{
        ID:        1,
        CreatedAt: time.Now(),
    }
    // ignoring err..
    b, _ := json.MarshalIndent(data, "", "  ")
    fmt.Println(string(b))
}

// main実行結果
// {
//   "ID": 1,
//   "CreatedAt": "2019-01-06T23:10:03.455595285+09:00"
// }

CreatedAtの時間の出力を日本の形式に変更する。それには、time.Timeの代わりに新しくstructを用意して、MarshallJSON()メソッドを自分で実装する。
新しく用意したstrcutをCreatedAtに使用する。

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type Data struct {
    ID        int
    CreatedAt JSONTime
}

type JSONTime time.Time

func (t JSONTime) MarshalJSON() ([]byte, error) {
    stamp := fmt.Sprintf("\"%s\"", time.Time(t).Format("2006年01月02日"))
    return []byte(stamp), nil
}

func main() {
    data := Data{
        ID:        1,
        CreatedAt: JSONTime(time.Now()),
    }
    // ignoring err..
    b, _ := json.MarshalIndent(data, "", "  ")
    fmt.Println(string(b))
}

// 実行結果
// {
//   "ID": 1,
//   "CreatedAt": "2019年01月06日"
// }

これで、CreatedAtの値が日本の時間形式で表示されるようになった。