2

I am using gson to convert serialized message to object, but I have problem with converting one attribute to java.sql.Timestamp

The start time attribute in JSON is

{...other_fields, "start_time": "2020-05-27 05:23:43.022610"}

And my Gson parser is initialized this way

new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss.S").create();

The object is parsed properly, but the start time has different minutes and seconds values as it should. The result of parse start time is: 2020-05-27 05:24:05.61

What am I missing?

Edit1:

Java Version: 1.8
Gson version: 2.8.2

Edit2:

After change format to yyyy-MM-dd HH:mm:ss (omitting milliseconds) I got the right result, but without milliseconds value. I can live with that, but it would be nice if someone could still explain this issue.

Smile
  • 3,832
  • 3
  • 25
  • 39
peter.cambal
  • 522
  • 6
  • 16
  • I think https://stackoverflow.com/questions/26044881/java-date-to-utc-using-gson can help you to understand that. – Maede May 27 '20 at 06:49
  • Well, with one `S`, `022610` is apparently interpreted as 22610 milliseconds. Your expected time plus 22610 milleseconds equals the result you get. – MC Emperor May 27 '20 at 06:52
  • @Maede This guy is experiencing timezone offset shift. I could solve that. My problem is that minutes, seconds, and milliseconds are totally messed up – peter.cambal May 27 '20 at 06:53
  • @MCEmperor yes it looks like it is this issue – peter.cambal May 27 '20 at 07:32

1 Answers1

2

GsonBuilder.setDateFormat() uses SimpleDateFormat.

And SimpleDateFormat doesn't support microseconds during parsing. S denotes miliseconds, which means only 3 places after the decimal.

This can be proved. In your JSON remove microseconds and use 2020-05-27 05:23:43.022 as input.

Output would be

2020-05-27 05:23:43.022

Timestamp does support microseconds and if you want to convert 2020-05-27 05:23:43.022610 (with microseconds) to Timestamp, you are better off writing a custom GSON deserializer

Edit : Sample deserializer for Timestamp

class TimestampDeserializer implements JsonDeserializer<Timestamp> {

    @Override
    public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        // Handle null checks or format check, etc.
        return Timestamp.valueOf(json.getAsString());
    }
}

Usage:

Gson gson = new GsonBuilder().serializeNulls().registerTypeAdapter(Timestamp.class, new TimestampDeserializer()).create();
Smile
  • 3,832
  • 3
  • 25
  • 39
  • I tried to use it with only 3 digits after decimal point and i was working as you said. Timestamp deserializer works like a charm as well. Thank you – peter.cambal May 27 '20 at 07:49