-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
proposal: encoding/json: support struct tag for time.Format in JSON Marshaller/Unmarshaller #21990
Comments
It's an interesting idea and maybe one to consider the next time we take a chunk of json decisions to make. For now the usual idiom is the wrapper type, as you described. Going to mark this as a proposal-hold for whenever the next rethink of json is. |
up! That would be convenient if it can specify time format through json tag, because formatting time is a more often behavior in most cases. |
The tag name maybe "layout", reuse by xml... |
Any update on this? This would be great for working with APIs, many of which have fixed time formats other than RFC-3339 |
Any Updates guys? |
I logged an issue I have been facing because of he time.Time package, assume RFC3339 is the only acceptable format in the json.Unmarshaller interface: When the defined time has trailing zero after the millisecond GO removes the trailing zero. The time becomes 2020-02-19 07:11:23.89 +0000 UTC This is an issue when other consuming application tries to consume this by defining a date formatter to get time from String value. The formatter does the strict matching. for example in java It will throw an exception while parsing 2020-02-19 07:11:23.89 +0000 UTC while will perfectly work for 2020-02-19 07:11:23.891 +0000 UTC The defect was closed saying I can use formatter and do parsed.Format("2006-01-02 15:04:05.000000000 -0700 MST") It's really a painful change, every time the user will have to reformat the time given the case below type activity struct { I read the data in this struct from MongoDB by using cur.Decode(&activity) |
👍 on the proposal. Hope I'm not breaking any rules here by commenting on this thread an alternative / complementary convenient way for changing a type json output. Idea is to allow custom serialization behaviour in the marshalling /unmarshalling process without having to touch the value being (un)marshalled. When calling json.Marshalf (new function) there could be a marshalers argument of type []TypeMarshaler that allows the caller to customise the process. Potential TypeMarshaler interface:
and corresponding
The TypeMarshaler would be applied to each field in the to marshal value that satisfies the CanHandle function. Motivation
|
I would like to support this request. Marshaling and Unmarshaling time (and potentially durations, though that might be more useful with ISO support) is a common task that currently requries boilerplate. Adding time format support to the json (and maybe yaml?) struct tags would be a nice simplification. I don't think we need broader research to show just how often that happens. |
@rsc is there any soonish timeframe for this (it's now been 4 years)? |
@rsc I think there is enough interest in this proposal that it should warrant looking into. I can tell you first had that some structures are very complex by virtue of the necessary data required for them, and having to add a whole lot of boilerplate code just to handle a date in a particular format makes for unnecessary and bloated code. I would think that this could be a simple modification of the Done the correct way, this can also be used for any sort of defined output (print, encoding/decoding, etc) |
It would be nice to move this proposal back into the proposal process. It seems it has very positive support looking at the OPs votes. |
Absolutely support this proposal. The aux solution linked in the OP seems to be the best option for library developers to avoid exposing users to unnecessary wrapper types but it would be nice if it wasn't necessary. |
+1 I have no idea why we still have to work around this ... |
@rsc given the current proposal process- could this be moved to active? Json in general could need some love and keeping these proposals on hold limits visibility. Seems there are no counter arguments except for "lets do this later" which would rather make it approved than on hold. |
There's been ongoing work to look at "json" holistically. In a prototype implementation, we've been exploring something like: type Foo struct {
Start time.Time `json:"start,format:DateTime"`
} where a For the following Go types, one could imagine the following supported format flags:
|
@dsnet much appreciated! A few more use cases I'm regularly seeing:
It would be really great if json could get an overhaul :) |
I was recently working with JSON-based APIs (i.e., Slack and Splunk) that represented timestamps as seconds since the Unix epoch as a JSON number. I don't have great answers but:
I'm not sure I understand. The
That's fairly particular. I haven't seen evidence for this, while I've seen evidence for formatting NaN and infinity as strings. |
Imho number, that's the typical format I'm seeing. If string is needed, this is already covered by
Given the type differs from other
I was referring to unmarshaling. That is not currently possible for the empty string, a regular use case I've seen that is also not solvable by using
Also
Again, I find this very useful. Marshaling NaN/Inf into strings can cause issues with decoding. When interested in "valid" values I would use a Maybe we should stick with |
Hi all, we kicked off a discussion for a possible "encoding/json/v2" package that addresses the spirit of this proposal. |
I will start with the proposal as a TL;DR before explaining the motivations behind it:
Proposal
It would be quite convenient if we could have the
encoding/json
package understand the format oftime.Time
as part of the struct definition. Something like this:This means that when you write
json.Unmarshal(data, &user)
, the json package will understand what format to parse/serialize the field with.Motivation/Experience Report
Currently, there are three workarounds:
type MyTime time.Time
: https://goplay.space/#APZL4Rzlm_Embedding time.Time in MyTime type: https://goplay.space/#q-oKnSTtQV
Implementing
json.Unmarshaller
on the parent struct: https://goplay.space/#mzb8MQfajlThose workarounds are not bad. However, I've noticed that they get out of hand once your codebase starts to scale.
Imagine having hundreds of structs with hundreds of fields where many of them could have different Time types just because they have different serialization formats, and nothing else.
The
time.Time
package, I think, might be too opinionated to assume RFC3339 is the only acceptable format in thejson.Unmarshaller
interface:go/src/time/time.go
Line 1366 in ce10e9d
I think it makes sense for it to be a default serialization format, but not the only one. The workaround is initially not bad at all. However, it gets cumbersome when your project scales.
I think this proposal shows that the above solution can make our code more declarative and less cumbersome. This echo's Rob Pike's talk in that here we can hide complexity behind a simple interface.
Lastly, this doesn't make or break my Go experience, but I personally see room for enhancement here.
The text was updated successfully, but these errors were encountered: