1
1

More than 1 year has passed since last update.

Go 言語で日付を JSON に変換するとき構造体を使わずに任意のフォーマットにする

Last updated at Posted at 2021-09-21

はじめに

Go 言語で構造体を JSON に変換すると time.Time 型の要素は RFC3339 フォーマットに変換されます。
これを他のフォーマットにしたくて

golang time json marshal

といったキーワードでググると time.Time 型を要素に持つ構造体 (jsonTime) を定義して MarshalJSON() メソッドを実装する、以下のような方法がヒットします。

type jsonTime struct {
    time.Time
}

func (j jsonTime) MarshalJSON() ([]byte, error) {
    return json.Marshal(j.Format("2006/01/02"))
}

これで解決なのですが、私にとっては jsonTime が構造体だと都合が悪かったため、それを使わない方法を調べました。

環境

% go version
go version go1.17.1 darwin/amd64

実装方法

まずコードを示します。

main.go
package main

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

type jsonTime time.Time

func (j jsonTime) MarshalJSON() ([]byte, error) {
    t := time.Time(j)
    return json.Marshal(t.Format("2006/01/02"))
}

type data struct {
    Id        int      `json:"id"`
    Name      string   `json:"name"`
    CreatedAt jsonTime `json:"created_at"`
}

func main() {
    d := data{
        Id:        1,
        Name:      "Foo Bar",
        CreatedAt: jsonTime(time.Now()),
    }

    bytes, _ := json.Marshal(d)
    fmt.Printf("%s", bytes)
}

先述した jsonTime 構造体の代わりに、defined type を使用して time.Time 型から jsonTime 型を定義しています。
ポイントは MarshalJSON() メソッドで jsonTime 型のレシーバを time.Time 型にキャストしているところです。

次に実行結果です。

{"id":1,"name":"Foo Bar","created_at":"2021/09/22"}

日付を任意のフォーマットにできました。

おわりに

私が探した限り、日付を任意のフォーマットの JSON に変換する方法はどれも同じものしか見つけられませんでした。
フォーマットのやり方にこそ差異はありましたが、構造体を使っていることは同じでした。
もしかして defined type では何か不都合があったりするのでしょうか?
それとも構造体以外も使えるのは当たり前すぎて誰も記事にしないだけ?

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1