Skip to content
New issue

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

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

Already on GitHub? # to your account

ZonedDateTime: ZoneId vs ZoneOffset behaviour #244

Open
armandino opened this issue Jun 17, 2022 · 8 comments
Open

ZonedDateTime: ZoneId vs ZoneOffset behaviour #244

armandino opened this issue Jun 17, 2022 · 8 comments
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue

Comments

@armandino
Copy link
Contributor

This issue is related to serializing ZonedDateTime with a ZoneOffset. When the same value is deserialized, we get back ZonedDateTime with a ZoneId instead. As a result, the seralized and deserialized dates are not equal.

Wanted to confirm whether this is a bug. If not, is there a recommended workaround?

Test case: https://github.com/armandino/jackson-modules-java8-bug-report

@cowtowncoder
Copy link
Member

It would seem ideal if the same representation would be returned with round-trip processing, but perhaps there are technical problems with that. I do not recall this being brought up before.
But if it was possible to get the same timezone representation back, that would seem preferable; I do not think change is intentional per se. So PR would be welcome if anyone wants to try it.

But one quick question: is the actual point-in-time still correct? (ignoring the different in representation of the timezone information). If not, that would be a bigger problem.

@armandino
Copy link
Contributor Author

Thanks for a quick response. I believe it is the same point in time, however I must admit I don't have an in-depth knowledge of java.time and might be overlooking something.

@cowtowncoder
Copy link
Member

Right, I would expect internal point in time to be same, which is at least some consolation.
As to the different in timezone representation, I vaguely recall there being some issues but I would have thought problem would go the other way: inability to retain zone id and only getting offset.

Still, a PR for (failing) test case would be useful; I could check that in (under .../failing/) in case anyone has time to look into what is happening (possibly me, but not necessarily)

@armandino
Copy link
Contributor Author

I added a test case #245

@armandino
Copy link
Contributor Author

I looked into this a bit more. Since by default, the date gets serialized into a decimal representation, e.g. {"date":1655571280.545632194}, there's not enough information to determine the original ZoneOffset or ZoneId. As a result, the UTC ZoneId is applied. For example, serializing ZonedDateTime.now(ZoneOffset.ofHours(-7)) and then deserializing produces a date with UTC ZoneId: 2022-06-18T17:11:46.583714647Z[UTC]. I'm not sure if a fix is possible (or needed) for this case.

There is another use case, deserializing dates in string format, such as "2022-06-18T10:11:46.583714647-07:00". Currently this also gets deserialzed as UTC: 2022-06-18T17:11:46.583714647Z[UTC]. However, in this case it should be possible to determine the original representation since ZonedDateTime.parse() can handle such strings automatically:

ZonedDateTime.parse("2022-06-18T10:11:46.583714647-07:00") // => 2022-06-18T10:11:46.583714647-07:00
ZonedDateTime.parse("2022-06-18T17:11:46.583714647Z[UTC]") // => 2022-06-18T17:11:46.583714647Z[UTC]

Then with SerializationFeature.WRITE_DATES_AS_TIMESTAMPS disabled, we should get a ZonedDateTime that is equal to the orginal value, as expected.

I updated the test case to reflect this.

@cowtowncoder cowtowncoder added 2.14 has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue labels Jun 20, 2022
@dscalzi
Copy link
Contributor

dscalzi commented Feb 19, 2023

see #267 for an in-depth explanation. I think these issues are related. In this case you may want to try disabling DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE. The default timezone in jackson is UTC, and by default the deserializer will adjust the zone to match the context's timezone.

@armandino
Copy link
Contributor Author

@dscalzi thank you for looking into this. I'll try your suggestion.

@cowtowncoder cowtowncoder removed the 2.14 label May 29, 2023
@cowtowncoder
Copy link
Member

FWTW, I implemented #281 which allows disabling ZoneId normalization and might help here. Will be included in 2.16.0 release.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue
Projects
None yet
Development

No branches or pull requests

3 participants