Quarkus: Date loose one day with JSONB

Created on 19 Jan 2020  路  10Comments  路  Source: quarkusio/quarkus

Describe the bug
Controller returns object with sql.date property test with value "1966-11-04"
But returned result, REST response, contains date with one day less :

{
test: "1966-11-03"
}

Expected behavior
to return same date as controller returns

Actual behavior
date returned is one day less

To Reproduce
Clone and build example repo - https://github.com/gintsgints/quarkusdateproblem

Environment (please complete the following information):
All versions in example project

kinbug triagupstream

Most helpful comment

@gintsgints I was able to reproduce the issue after setting my JVM timezone to Europe/Sofia

What's happening here is that the java.sql.Date has no timezone precision on it, but when Yasson serializes the value it attempts to convert the value to a java.time.Instant as an intermediary step which forces it to take into account Timezone. Yasson assumes that a java.sql.Date of 1966-11-04 (or any date) is the beginning of that day in UTC, and when the value is serialized it uses the users timezone, which in this case is UTC -3:00 or 1966-11-03T21:00:00 which gets truncated to 1966-11-03.

@gsmet I was able to reproduce this issue outside of Quarkus, so it's just a Yasson issue. Can we move this issue over to https://github.com/eclipse-ee4j/yasson?

All 10 comments

@aguibert mind taking a look at this one?

@geoand yep I can have a look, can you assign to me please?

Thanks @aguibert, I assigned it to you

I suspect a time zone related issue.

indeed @gsmet, unfortunately these sort of issues are fairly common when pre-java.time APIs are used

@gintsgints I was able to reproduce the issue after setting my JVM timezone to Europe/Sofia

What's happening here is that the java.sql.Date has no timezone precision on it, but when Yasson serializes the value it attempts to convert the value to a java.time.Instant as an intermediary step which forces it to take into account Timezone. Yasson assumes that a java.sql.Date of 1966-11-04 (or any date) is the beginning of that day in UTC, and when the value is serialized it uses the users timezone, which in this case is UTC -3:00 or 1966-11-03T21:00:00 which gets truncated to 1966-11-03.

@gsmet I was able to reproduce this issue outside of Quarkus, so it's just a Yasson issue. Can we move this issue over to https://github.com/eclipse-ee4j/yasson?

hi @gintsgints, I've proposed a fix in Yasson, but it will be a few weeks until a new release is available since Yasson just made a release last week.

You can workaround the issue in the short-term in a couple different ways:

  1. Use a more modern type in your model such as java.time.LocalDate (probably preferred solution)
  2. Change the property type from java.sql.Date to String and use sqlDate.toString() and java.sql.Date.valueOf(str)
  3. Register a custom JsonbAdapter for the java.sql.Date type with your Jsonb instance like so:
    public class SqlDateAdapter implements JsonbAdapter<java.sql.Date, String> {
        @Override
        public String adaptToJson(java.sql.Date obj) throws Exception {
            return obj.toString();
        }

        @Override
        public java.sql.Date adaptFromJson(String obj) throws Exception {
            return java.sql.Date.valueOf(obj);
        }
    }

And register it as described here: https://quarkus.io/guides/rest-json#configuring-json-support

No problem. I can wait for now, till fix comes out. Many thanks for great project

The fix for this issue is now merged in Yasson master, and will be available in the next version of Yasson (version 1.0.7)

Was this page helpful?
0 / 5 - 0 ratings