huma icon indicating copy to clipboard operation
huma copied to clipboard

time.RFC3339

Open jc-fireball opened this issue 1 year ago • 4 comments

Hi

We've been migrating to huma. We notice the default time format is using RFC3339nano in json response. Is there anyway we can set the time format in json to time.RFC3339

jc-fireball avatar Sep 03 '24 04:09 jc-fireball

@jc-fireball sorry for the slow response on this! The Go JSON marshaler controls this behavior via the time.Time type's MarshalJSON method. See https://pkg.go.dev/time#Time.MarshalJSON and the official implementation at https://cs.opensource.google/go/go/+/refs/tags/go1.23.2:src/time/time.go;l=1392.

You should be able to create a custom type wrapping time.Time that implements custom marshaling as explained at https://stackoverflow.com/questions/23695479/how-to-format-timestamp-in-outgoing-json. If you can't use custom types then you may have to wrap the JSON marshaler itself in the huma.Config formats to special case certain behaviors.

danielgtaylor avatar Oct 08 '24 23:10 danielgtaylor

As you just point out, the Golang default time.Time marshal is using RFC3339, however Huma default to RFC3339Nano

image

jc-fireball avatar Oct 09 '24 18:10 jc-fireball

Only the time.Time in header is in different way which allows us to override the format but not in other places like json field.

jc-fireball avatar Oct 09 '24 18:10 jc-fireball

@jc-fireball that specific code you linked to is Huma's custom handling of parameters (path/query/header/cookie). You can change that time format like this using Go's time formatting:

type MyInput struct {
  MyTime time.Time `query:"myTime" timeFormat:"..."`
}

Keep in mind though this is not for the JSON body, which is controlled by the encoding/json package instead of Huma itself which I linked to above. This is just how Go works with JSON encoding, but you can preprocess times to get the output you want, for example:

t := time.Now()
t = t.Add(123 * time.Millisecond)
b, _ := json.Marshal(t)
fmt.Println(string(b)) // prints with milliseconds

t = t.Truncate(time.Second)
b, _ = json.Marshal(t)
fmt.Println(string(b)) // prints without milliseconds

https://go.dev/play/p/ayaM260jpFQ

danielgtaylor avatar Oct 09 '24 22:10 danielgtaylor