web-dev-qa-db-ja.com

time.Timeフィールドを使用したGolang JSON除外

2つの時間フィールドを含む構造体をjsmarshalしようとしています。しかし、時間の値がある場合にのみ、フィールドが通過するようにします。だから私はjson:",omitempty"を使用していますが、機能していません。

Date値をjson.Marshalが空(ゼロ)値として扱い、json文字列に含めないように設定するにはどうすればよいですか?

遊び場: http://play.golang.org/p/QJwh7yBJlo

実際の結果:

{「タイムスタンプ」:「2015-09-18T00:00:00Z」、「日付」:「0001-01-01T00:00:00Z」}

望ましい結果:

{「タイムスタンプ」:「2015-09-18T00:00:00Z」}

コード:

package main

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

type MyStruct struct {
    Timestamp time.Time `json:",omitempty"`
    Date      time.Time `json:",omitempty"`
    Field     string    `json:",omitempty"`
}

func main() {
    ms := MyStruct{
        Timestamp: time.Date(2015, 9, 18, 0, 0, 0, 0, time.UTC),
        Field:     "",
    }

    bb, err := json.Marshal(ms)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(bb))
}
31
Joe Bergevin

omitemptyタグオプションは、structであるため、_time.Time_では機能しません。構造体には「ゼロ」値がありますが、それはすべてのフィールドにゼロ値がある構造体値です。これは「有効な」値なので、「空」として扱われません。

しかし、ポインタを_*time.Time_に変更するだけで機能します(nilポインタは、jsonマーシャリング/アンマーシャリングでは「空」として扱われます)。この場合、カスタム Marshaler を記述する必要はありません。

_type MyStruct struct {
    Timestamp *time.Time `json:",omitempty"`
    Date      *time.Time `json:",omitempty"`
    Field     string     `json:",omitempty"`
}
_

それを使用して:

_ts := time.Date(2015, 9, 18, 0, 0, 0, 0, time.UTC)
ms := MyStruct{
    Timestamp: &ts,
    Field:     "",
}
_

出力(必要に応じて):

_{"Timestamp":"2015-09-18T00:00:00Z"}
_

Go Playground で試してください。

ポインタに変更できない、または変更したくない場合でも、カスタム Marshaler および Unmarshaler 。その場合、 Time.IsZero() メソッドを使用して、_time.Time_値がゼロ値であるかどうかを判断できます。

62
icza

カスタムマーシャル形式の自己時間型を定義し、代わりにどこでも使用できますtime.Time

http://play.golang.org/p/S9VIWNAaVS

package main

import "fmt"
import "time"
import "encoding/json"

type MyTime struct{
    *time.Time
}

func (t MyTime) MarshalJSON() ([]byte, error) {
        return []byte(t.Format("\"2006-01-02T15:04:05Z\"")), nil
   }


   // UnmarshalJSON implements the json.Unmarshaler interface.
    // The time is expected to be a quoted string in RFC 3339 format.
func (t *MyTime) UnmarshalJSON(data []byte) (err error) {
        // Fractional seconds are handled implicitly by Parse.
        tt, err := time.Parse("\"2006-01-02T15:04:05Z\"", string(data))
        *t = MyTime{&tt}
        return
   }

func main() {
    t := time.Now()
    d, err := json.Marshal(MyTime{&t})
    fmt.Println(string(d), err)
    var mt MyTime
    json.Unmarshal(d, &mt)
    fmt.Println(mt)
}
2
Jiang YD