I intent to serialize time.Time
to have UTC timezone and in RFC3339 format.
So I created following custom data type called Time
that embeds time.Time
.
package main
import (
"encoding/json"
"time"
)
type Time struct {
time.Time
}
func (t *Time) UnmarshalJSON(b []byte) error {
ret, err := time.Parse(time.RFC3339, string(b))
if err != nil {
return err
}
*t = Time{ret}
return nil
}
func (t Time) MarshalJSON() ([]byte, error) {
return []byte(t.UTC().Format(time.RFC3339)), nil
}
func main() {
type User struct {
CreatedAt Time `json:"created_at"`
}
user := User{CreatedAt: Time{time.Now()}}
_, err := json.Marshal(user)
if err != nil {
panic(err)
}
}
When this data is tried to marshal with json.Marshal
I get following error
json: error calling MarshalJSON for type main.Time: invalid character '-' after top-level value
I have 2 queries
- Why above code is throwing the error?
- Is this the right way to serialise and deserialise
time.Time
to and from a desired format in an API
Thanks in advance!
CodePudding user response:
The text 2009-11-10T23:00:00Z
is not a valid JSON value, but "2009-11-10T23:00:00Z"
is. Note the quotes.
Use the following function to format Time as a JSON string.
func (t Time) MarshalJSON() ([]byte, error) {
b := make([]byte, 0, len(time.RFC3339) 2)
b = append(b, '"')
b = t.AppendFormat(b, time.RFC3339)
b = append(b, '"')
return b, nil
}