I want to encode my time.Time
fields as numeric Unix time and I would prefer not to implement custom MarshalJSON functions for each and every struct, since I have lots and lots of structs.
So, I tried defining a type alias as such:
type Timestamp time.Time
And implementing MarshalJSON on it like so:
func (t Timestamp) MarshalJSON() ([]byte, error) {
return []byte(strconv.FormatInt(t.Unix(), 10)), nil
}
But that gives me a t.Unix undefined (type Timestamp has no field or method Unix)
, which doesn't make sense to me. Shouldn't Timestamp
'inherit' (I know that's probably the wrong term) all functions of time.Time
?
I also tried using a type assertion like so:
strconv.FormatInt(t.(time.Time).Unix(), 10)
But that also fails, complaining about an invalid type assertion: invalid type assertion: t.(time.Time) (non-interface type Timestamp on left)
You need to convert your type back to a time.Time
to have access to its methods. Named types do not "inherit" the methods of their underlying types (to do that, you need embedding).
func (t Timestamp) MarshalJSON() ([]byte, error) {
return []byte(strconv.FormatInt(time.Time(t).Unix(), 10)), nil
}
Also, just as a matter of personal preference, I tend to preferred fmt.Sprintf("%v", i)
over strconv.FormatInt(i, 10)
or even strconv.Itoa(i)
. Honestly not sure which is faster, but the fmt
version seems easier to read, personally.