Reputation: 2245
I'm using a service that requires time inputs to be formatted in such a way that a decimal place is always included, even if the time itself is right on the second mark.
For example: ValueError: time data '2021-01-07T21:09:59Z' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'
I know that by default, json.Marshal
will format time.Time
types into RFC3339 format, so I tried to implement a custom Marshaler for my struct, which converts the time into RFC3339Nano first ("2006-01-02T15:04:05.999999999Z07:00"
:
func (f *MyStruct) MarshalJSON() ([]byte, error) {
type Alias MyStruct
return json.Marshal(&struct {
*Alias
Timestring string `json:"time"`
}{
Alias: (*Alias)(f),
Timestring: f.Time.Format(time.RFC3339Nano),
})
}
However, I discovered that RFC3339Nano will still omit sub-seconds if the time itself is right on the second mark.
I could simply manipulate the string to add on a .000
if it is missing, but I was wondering if there is a cleaner way of achieving this in go?
Upvotes: 1
Views: 797
Reputation: 31751
A decimal point followed by one or more zeros represents a fractional second, printed to the given number of decimal places. A decimal point followed by one or more nines represents a fractional second, printed to the given number of decimal places, with trailing zeros removed.
https://golang.org/pkg/time/#pkg-constants
So use zeros instead of nines until the desired precision is reached:
t := time.Date(2021, 1, 7, 21, 9, 59, 0, time.UTC)
fmt.Println(t.Format("2006-01-02T15:04:05.000Z07:00")) // 2021-01-07T21:09:59.000Z
Try it on the playground: https://play.golang.org/p/xqFP_2g3jYP
Upvotes: 3