亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

JSON omitempty with time.Time 字段

JSON omitempty with time.Time 字段

Go
30秒到達戰場 2021-11-08 16:03:27
嘗試對包含 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 mainimport (    "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))}
查看完整描述

3 回答

?
隔江千里

TA貢獻1906條經驗 獲得超10個贊

該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上試一試。


如果您不能或不想將其更改為指針,您仍然可以通過實現自定義Marshaler和Unmarshaler. 如果這樣做,您可以使用該Time.IsZero()方法來確定某個time.Time值是否為零值。


查看完整回答
反對 回復 2021-11-08
?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

您可以為自定義元帥格式定義自己的時間類型,并在任何地方使用它 time.Time


https://play.golang.org/p/C8nIR1uZAok


package main


import (

    "bytes"

    "encoding/json"

    "fmt"

    "time"

)


type MyTime struct {

    *time.Time

}


func (t MyTime) MarshalJSON() ([]byte, error) {

    return []byte(t.Format("\"" + time.RFC3339 + "\"")), 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) {


    // by convention, unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.

    if bytes.Equal(data, []byte("null")) {

        return nil

    }


    // Fractional seconds are handled implicitly by Parse.

    tt, err := time.Parse("\""+time.RFC3339+"\"", 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)

}


查看完整回答
反對 回復 2021-11-08
?
RISEBY

TA貢獻1856條經驗 獲得超5個贊

作為 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),

        })

    }

}

這從http://choly.ca/post/go-json-marshalling/借用


OPs 案例有兩個時間字段,這會使它變得更加復雜。(你必須檢查兩者都不是,兩者都是空的!)


可能有更好的方法來實現這一點,所以歡迎提出意見。


查看完整回答
反對 回復 2021-11-08
  • 3 回答
  • 0 關注
  • 284 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號