Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode unix timestamps into time.Time just like the UnixTime option for Marshal? #14

Closed
takanuva15 opened this issue Dec 18, 2024 · 3 comments

Comments

@takanuva15
Copy link

Hi, this library has a great option UnixTime that "Encode[s] time.Time values as JSON numbers representing Unix timestamps".

In my case, I have to deal with json that sends time values as integer unix timestamps and unmarshal it into structs using time.Time fields. The default encoding/json just throws an error when it sees the unix timestamps, and our team's codebase is too large to replace every time.Time field with a custom type just for the sake of these int timestamps.

I'm aware this library is for marshalling only, but do you know if there's a way we can somehow apply this behavior to work for unmarshalling as well, either through this library or another? (I looked at goccy/go-json but I don't see an option for customizing unmarshal for time.Time)

@wI2L
Copy link
Owner

wI2L commented Dec 18, 2024

@takanuva15
This library does only encoding, and I have no plan to add unmarshaling support.
I'm not aware of any other lib that support time.Time values like this one. The recommended approach would always be to implement a custom type with a specific json.Unmarshaler interface if you use a lib (either official or another one) that implement the same API as encoding/json.

@takanuva15
Copy link
Author

takanuva15 commented Dec 18, 2024

Ok after spending hours of looking at Golang code, I finally figured out a way to customize the decoding of epoch milli timestamps into time.Time fields in my own struct without needing to make a dummy wrapper type.

Note: This does require the new experimental json package being developed for Golang, which will eventually be converted to encoding/json/v2 once it gets out of development phase.

go get github.com/go-json-experiment/json

Define your struct like so:

type Author struct {
	CreatedAt             *time.Time            `json:"createdAt,omitempty,omitzero,format:unixmilli"`
}

And then unmarshal json into the Author struct using the above package:

import (
	"fmt"
	"time"

	"github.com/go-json-experiment/json/v1"
)

func main() {
	jsonStr := `{"createdAt":1734558308666}`
	a := Author{}
	_ = json.Unmarshal([]byte(jsonStr), &a)
	res, _ := json.Marshal(a)
	fmt.Println(string(res))
}

Output: {"createdAt":1734558308666}


EDIT: As a bonus, I got this to work in gin as well for serializing responses using the new json package. See this comment for details

@wI2L
Copy link
Owner

wI2L commented Dec 19, 2024

@takanuva15 Good find. Didn't notice that feature myself, might have been added after I looked up the v2 experiment, or simply missed it perhaps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants