一尘不染

JSON时空性带time.Time字段

go

尝试对包含2个时间字段的结构进行JSON编组。但我只希望该字段具有时间值才能通过。所以我正在使用,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))
}

阅读 324

收藏
2020-07-02

共1个答案

一尘不染

omitempty标签选项不能正常工作time.Time,因为它是一个struct。结构有一个“零”值,但这是所有字段都为零的结构值。这是一个“有效”值,因此不会被视为“空”。

但是只需将其更改为指针:*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上尝试一下。

如果您不能或不想将其更改为指针,则仍可以通过实现custom
Marshaler和来实现所需的功能Unmarshaler。如果这样做,则可以使用该Time.IsZero()方法来确定一个time.Time值是否为零值。

2020-07-02