When serializing / deserializing an object with the Date and Time classes of the new java.time API, the results are diferent from expected.
For example, here's a java.util.Date serialized with gson (using version 2.8.0):
"created": "2017-04-07T18:07:00",
and here's a java.time.LocalDate:
"expiration": {
"year": 2017,
"month": 4,
"day": 7
}
the expected result for javatime api was a ISO-8601.
This is due to some historical baggage where Gson will happily serialize any object inside the platform package (java.*). Ideally Gson would throw an error when you did this, but alas, we can't make that change. Also Gson's built-in support of java.util.Date is also historical baggage we cannot remove or change.
The correct solution here would be to register your own type adapter for the java.time.* types so that they show up as ISO 8601 when serialized and deserialization parses them appropriately.
A quick search yields https://github.com/gkopff/gson-javatime-serialisers which you may just be able to drop in, but otherwise building a TypeAdapter yourself for these shouldn't be too bad.
a) still it would be great to have an "official" gson plugin/package with Java 8 types support
b) a note in https://github.com/google/gson/blob/master/UserGuide.md with the explanation about targetting Java 6 would helpe otherwise
Dates come in from JSON as string values, right?
I keep seeing examples of registering adapters for specific Java classes like ZonedDateTime etc, but how would Gson know that you want to convert a particular incoming _string_ value into a ZonedDateTime specifically?
@jugimaster Because you tell Gson the expected class when deserializing:
SomeClass obj = gson.fromJson(jsonString, SomeClass.class);
So Gson would either know it from there, or if your ZonedDateTime is a field of the class, then Gson will know by reflection that this field is supposed to be a ZonedDateTime (unless you use an abstract superclass/interface).
Because you tell Gson the expected class when deserializing
But I'm not using JavaBeans/"domain model classes" - I just have Maps, and I was calling Gson from Clojure too.
Can strings be converted into Dates when deserializing into a Map?
@jugimaster I'm not familiar with clojure unfortunately, but as far as I remember in Java, if you're using a Map<String, Date>, Gson would know the expected type for your map's values is Date.
However, you seem to be using a "map of maps" kind of structure without generic type information (even maybe using mixed types as values in your maps), and in this case I don't see how Gson could possibly infer a more accurate type than the JSON type itself, which would be String in your case.
Again, I'm speaking for Java, but I guess if you want statically typed data, you should define your classes. If you don't, then you should expect to handle this kind of conversions yourself at runtime.
Please someone from the Gson team correct me if I'm wrong.
However, you seem to be using a "map of maps" kind of structure without generic type information (even maybe using mixed types as values in your maps), and in this case I don't see how Gson could possibly infer a more accurate type than the JSON type itself, which would be String in your case.
Right :)
But with Jackson, I was able to configure my own class to handle incoming Strings, and convert the ones that represent dates into Date instances. I couldn't figure out how to do that with Gson.
I may be completely missing something here, of course.
Most helpful comment
a) still it would be great to have an "official" gson plugin/package with Java 8 types support
b) a note in https://github.com/google/gson/blob/master/UserGuide.md with the explanation about targetting Java 6 would helpe otherwise