I’m trying to define a Time
struct which implements the Marshaler
interface such that, when it is marshaled to JSON, it is represented in the format YYYY-mm-ddTHH:MM:SSZ
, that is, the time is converted to UTC and rounded to the nearest second. I’ve tried the following program:
package main
import (
"encoding/json"
"fmt"
"log"
"time"
)
type Time struct {
time.Time
}
func (t *Time) MarshalJSON() ([]byte, error) {
return []byte(t.Time.UTC().Round(time.Second).Format(time.RFC3339)), nil
}
func main() {
tm := time.Now()
// tm := time.Now().UTC().Round(time.Second)
tmJSON, err := json.Marshal(tm)
if err != nil {
log.Fatalf("marshal time: %v", err)
}
fmt.Println(string(tmJSON))
}
When I run this, however, it prints
> go run main.go
"2022-12-07T16:32:51.494597-08:00"
If, by contrast, I pass in time.Now().UTC().Round(time.Second)
as the input to be marshaled (i.e., use the commented-out line in the snippet above), I get the desired output:
> go run main.go
"2022-12-08T00:41:10Z"
My question is: why can’t I perform the conversion to UTC and rounding to the nearest second in the MarshalJSON
method itself?
2
Answers
what are you trying to do?
I tried running your
MarshalJSON
function and it works as expectedhere is what I tried to do:
and i got the following output:
The first line is your previous output and the second output is of your
MarshalJSON
function.You can use
AppendFormat
to convert your time string into buffer.Also in your question you are not initialising your
Time
struct for Marshalling.Here is a probable solution