Golang JSON omitempty Over time. Time field

An attempt by json Marshal to create a structure containing 2 temporary fields. But I want the field to work out if it has a time value. Therefore, I use json:",omitempty" , but it does not work.

What can I set the Date parameter to json.Marshal will treat it as an empty (zero) value and not include it in the json string?

Playground: http://play.golang.org/p/QJwh7yBJlo

Actual result:

{"Mark": "2015-09-18T00: 00: 00Z", "Date": "0001-01-01T00: 00: 00Z"}

Desired Result:

{"Mark": "2015-09-18T00: 00: 00Z"}

the code:

 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)) } 
+10
json time go
Sep 18 '15 at 4:20
source share
2 answers

The omitempty tag parameter omitempty not work with time.Time , since it is a struct . There is a “null” value for structs, but this is a structure value, where all fields have null values. This is a "real" value, therefore it is not considered as "empty".

But just changing it to a pointer: *time.Time , it will work ( nil pointers are considered as "empty" for json marshaling / unmarshaling). Therefore, there is no need to write a custom Marshaler in this case:

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

Using it:

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

Output (optional):

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

Try it on the go playground .

If you cannot or do not want to change it to a pointer, you can still achieve what you want by doing Marshaler and Unmarshaler . If you do, you can use the Time.IsZero() method to decide if time.Time null value.

+26
Sep 18 '15 at 7:17
source share

you can determine the type of your time for the custom marshal format and use it everywhere instead of 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
Sep 18 '15 at 5:17
source share



All Articles