Things to Watch Out for When Using json.Unmarshal with Time in Go
A Story About a Certain 3rd Party API
While working with a certain 3rd party API in Go, I came across an API that returned JSON like the following.
1 | { |
When you store this JSON into a struct with json.Unmarshal, what format does it come back in?
1 | type Hoge struct { |
The format turned out to be 1981-01-07 17:44:13 +0000 UTC.
Where is the format defined?
Following the code, the UnmarshalJSON receiver on *time.Time hardcodes RFC3339 and calls time.Parse with it.
Reference: golang.org/src/time/time.go
1 | // UnmarshalJSON implements the json.Unmarshaler interface. |
I ended up searching the encoding/json package by mistake, oops.
How Can You Handle the Format Freely?
I defined a custom type.
1 | package main |
- Receive the API response into a custom type
type JSONTime string - When you want to do calculations or comparisons on the time, call
t.Time()to get atime.Timeand compute with that
This setup is quite convenient.
Another Real-World Example: Slack API usergroups.create
The Slack API usergroups.create returns date_create in the response as a timestamp like 1446746793, so using type JSONTime int64 works well.
1 | // JSONTime exists so that we can have a String method converting the date |
Summary
- The
UnmarshalJSONreceiver on*time.Timereturns the value in theRFC3339format. - To use an arbitrary format, create a custom type, define an
UnmarshalJSONreceiver on it, and specify the format when parsing.
I hope this is helpful.
References
Things to Watch Out for When Using json.Unmarshal with Time in Go