Home > Mobile >  json: error calling MarshalJSON for type main.Time: invalid character '-' after top-level
json: error calling MarshalJSON for type main.Time: invalid character '-' after top-level

Time:03-09

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

  1. Why above code is throwing the error?
  2. 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
}
  • Related