Not planned
Description
The following snippet illustrates the problem:
final Gson gson = new GsonBuilder().create();
final OffsetDateTime before = OffsetDateTime.now();
System.out.println(String.format("Before: %s", before));
final String serialized= gson.toJson(before);
System.out.println(String.format("Serialized: %s", serialized));
final OffsetDateTime after = gson.fromJson(serialized, OffsetDateTime.class);
System.out.println(String.format("After: %s", after));
One run output the following:
Before: 2019-05-03T16:31:25.171+02:00
Serialized: {"dateTime":{"date":{"year":2019,"month":5,"day":3},"time":{"hour":16,"minute":31,"second":25,"nano":171000000}},"offset":{"totalSeconds":7200}}
After: 2019-05-03T16:31:25.171null
Note that on the last line, after the serialization roundtrip, the timezone is dropped. Why? Is this a bug in gson, or a configuration error on my part?
This is with gson 2.8.5 and
>java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (Zulu 8.38.0.13-CA-win64) (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (Zulu 8.38.0.13-CA-win64) (build 25.212-b04, mixed mode)
Activity
tomasaschan commentedon May 4, 2019
After doing some research on this, I think I can summarize the root cause:
ZoneOffset
, gson sets thetotalSeconds
, but not theid
(probably as intended, becauseid
is markedtransient
)toString
on aZoneOffset
, it simply outputs itsid
toString
on anOffsetDateTime
, it returnsdatetime.toString() + offset.toString()
I thus, all the actual information does survive the round-trip, but the redundancy in
ZoneOffset
is not handled according to the, presumed, intended behavior of the type.I understand that it's too late to change gson's handling of serializing
OffsetDateTime
and friends to use eg ISO date strings instead, but IIUC it should be possible to adapt how gson deserializesZoneOffset
specifically, to calculate and set the ID string too (for example,{"totalSeconds": 7200}
should have the ID string set to"+02:00"
).Is this something that should be done inside gson, or as a plugin? Would a PR with this functionality have any chance of being accepted?
janos-laszlo commentedon Dec 7, 2019
I tried it with a custom TypeAdapter:
https://www.tutorialspoint.com/gson/gson_custom_adapters.htm
and solves this problem in my case
cesarochoa2006 commentedon Jul 7, 2021
Please check this project. I have found the OffsetDateTime converter of theirs fully working and usefull
https://github.com/aaronweihe/ThreeTen-Backport-Gson-Adapter
Marcono1234 commentedon Aug 6, 2022
The underlying issue here is that Gson does not have any built-in type adapters for the
java.time
classes (#1059) and you are (by accident?) relying on reflection-based serialization for these classes. This should be avoided because it makes you dependent on the implementation details of these classes.As mentioned in the comments above, prefer using a custom type adapter for the class.