LoginSignup
57
43

More than 5 years have passed since last update.

データをJSONに変換するときに任意のフォーマットを設定する

Posted at

前置き

構造体をJSONにする場合、encoding/jsonfunc Marshal(v interface{}) ([]byte, error)を利用する。

package main

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

type Data struct {
  Id        int       `json:"id"`
  Title     string    `json:"title"`
  CreatedAt time.Time `json:"created_at"`
}

func main() {
  loc, _ := time.LoadLocation("Asia/Tokyo")
  d := Data{
    1,
    "HelloWorld",
    time.Date(2014, 8, 25, 0, 0, 0, 0, loc),
  }

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

}

実行結果(本来は改行無し)

{
  "id":1,
  "title":"HelloWorld",
  "created_at":"2014-08-25T00:00:00+09:00"
}

この場合、created_atのフォーマットを2014-08-25T00:00:00+09:00から2014-08-25にしたいとする。

formatを設定する

JSONへMarshal()が実行される場合、それぞれの型のMarshalJSON()が実行される。
上の場合created_atTimeの関数であるfunc UnmarshalJSON()を利用している。

http
func (t *Time) UnmarshalJSON(data []byte) (err error) {
    // Fractional seconds are handled implicitly by Parse.
    *t, err = Parse(`"`+RFC3339+`"`, string(data))
    return
}

つまりは、RFC3339形式のstring型に変換している。
なので、新規にUnmarshalJSON()を持った構造体を新しく作成する必要がある。

// 独自のjsonTimeを作成
type jsonTime struct {
  time.Time
}

// formatを設定
func (j jsonTime) format() string {
  return j.Time.Format("2006-01-02")
}

// MarshalJSON() の実装
func (j jsonTime) MarshalJSON() ([]byte, error) {
  return []byte(`"` + j.format() + `"`), nil
}

// CreatedAtの型をtime.TimeからjsonTimeに変更
type Data struct {
  Id        int      `json:"id"`
  Title     string   `json:"title"`
  CreatedAt jsonTime `json:"created_at"`
}

func main() {
  loc, _ := time.LoadLocation("Asia/Tokyo")
  d := Data{
    1,
    "HelloWorld",
    jsonTime{time.Date(2014, 8, 25, 0, 0, 0, 0, loc)},
  }

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

実行結果(改行は無し)

{
  "id": 1,
  "title": "HelloWorld",
  "created_at": "2014-08-25"
}

まとめ

  • JSONのMarshalをする場合、値の型のUnmarshalJSON()が使われる。
  • UnmarshalJSON()を独自で実装するために新しい型を実装する必要がある。

参考

57
43
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
57
43