I have JSONs with a date-time attribute in the format \"2014-03-10T18:46:40.000Z\", which I want to deserialize into a java.time.LocalDateTime field using Gson.
When
The error occurs when you are deserializing the LocalDateTime attribute because GSON fails to parse the value of the attribute as it's not aware of the LocalDateTime objects.
Use GsonBuilder's registerTypeAdapter method to define the custom LocalDateTime adapter. Following code snippet will help you to deserialize the LocalDateTime attribute.
Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
Instant instant = Instant.ofEpochMilli(json.getAsJsonPrimitive().getAsLong());
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
}).create();
Following worked for me.
Java:
Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return LocalDateTime.parse(json.getAsString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); }
}).create();
Test test = gson.fromJson(stringJson, Test.class);
where stringJson is a Json which is stored as String type
Json:
"dateField":"2020-01-30 15:00"
where dateField is of LocalDateTime type which is present in the stringJson String variable.
To extend @Randula's answer, to parse a zoned date time string (2014-03-10T18:46:40.000Z) to JSON:
Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
return ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString()).toLocalDateTime();
}
}).create();
To even further extend @Evers answer:
You can further simplify with a lambda like so:
GSON GSON = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json, type, jsonDeserializationContext) ->
ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString()).toLocalDateTime()).create();