JSON随时间为空。时间字段
尝试json封送包含2个时间字段的结构。但我只希望字段有时间值时通过。所以我使用了JSON随时间为空。时间字段,json,go,time,struct,Json,Go,Time,Struct,尝试json封送包含2个时间字段的结构。但我只希望字段有时间值时通过。所以我使用了json:,省略empty“,但它不起作用 我可以将日期值设置为什么,以便json.Marshal将其视为空(零)值,而不将其包含在json字符串中 游乐场: 实际结果: {“时间戳”:“2015-09-18T00:00:00Z”,“日期”:“0001-01-01T00:00:00Z”} 期望的结果: {“时间戳”:“2015-09-18T00:00:00Z”} 代码: 您可以为自定义封送处理格式定义自己的时间类型
json:,省略empty“
,但它不起作用
我可以将日期值设置为什么,以便json.Marshal将其视为空(零)值,而不将其包含在json字符串中
游乐场:
实际结果:
{“时间戳”:“2015-09-18T00:00:00Z”,“日期”:“0001-01-01T00:00:00Z”}
期望的结果:
{“时间戳”:“2015-09-18T00:00:00Z”}
代码:
您可以为自定义封送处理格式定义自己的时间类型,并在任何地方使用它
ommitempty
标记选项不适用于time.time
,因为它是一个struct
。结构有一个“零”值,但这是一个所有字段都有其零值的结构值。这是一个“有效”值,因此不会将其视为“空”
但只需将其更改为指针:*time.time
,它就可以工作(nil
指针在json封送/解封时被视为“空”)。因此,在这种情况下无需编写自定义:
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: "",
}
输出(根据需要):
试穿一下
如果您不能或不想将其更改为指针,您仍然可以通过实现自定义和。如果这样做,您可以使用该方法确定
time.time
值是否为零值。作为icza答案的后续,这里有一个自定义封送拆收器,它省略了一个空的日期字段,但保持其余字段不变
func (ms *MyStruct) MarshalJSON() ([]byte, error) {
type Alias MyStruct
if ms.Timestamp.IsZero() {
return json.Marshal(&struct {
Timestamp int64 `json:",omitempty"`
*Alias
}{
Timestamp: 0,
Alias: (*Alias)(ms),
})
} else {
return json.Marshal(&struct {
*Alias
}{
Alias: (*Alias)(ms),
})
}
}
这是从
OPs案例有两个时间域,这将使其更加复杂。(你必须检查两个都没有,或者都是空的!)
可能有更好的方法来实现这一点,所以欢迎评论。该功能。实现您的目标最简单的方法可能是让MyStruct实现。很好的了解和很好的建议。谢谢这是一个很好的答案。谢谢感觉这个答案救了我的命。
ts := time.Date(2015, 9, 18, 0, 0, 0, 0, time.UTC)
ms := MyStruct{
Timestamp: &ts,
Field: "",
}
{"Timestamp":"2015-09-18T00:00:00Z"}
func (ms *MyStruct) MarshalJSON() ([]byte, error) {
type Alias MyStruct
if ms.Timestamp.IsZero() {
return json.Marshal(&struct {
Timestamp int64 `json:",omitempty"`
*Alias
}{
Timestamp: 0,
Alias: (*Alias)(ms),
})
} else {
return json.Marshal(&struct {
*Alias
}{
Alias: (*Alias)(ms),
})
}
}