Home > Software engineering >  Deserialize Java 8 LocalDateTime with Jackson
Deserialize Java 8 LocalDateTime with Jackson

Time:03-10

In Jackson 2.11 was change about LocalDataTime format during serialization. I have problem with deserialization. I've found solution to override configuration from objectMapper like bellow:

@Configuration
public class AppConfig {

    @Bean
    public ObjectMapper objectMapper()
    {
        ObjectMapper mapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        mapper.registerModule(javaTimeModule);
        return mapper;
    }

but I've still problem with deserialization json string to java model:

@Data
public class CustomLocalDataTime {


    //@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx") <- not working
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS") // <- not working
    // @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", shape = JsonFormat.Shape.STRING) <- not working
    private  LocalDateTime date;
}

So I am receiving from some response localdatatime in format example: 2022-04-05T05:00:00.000 00:00 and during deserialization I am still getting error:

    com.fasterxml.jackson.databind.exc.InvalidFormatException: 
    Cannot deserialize value of type `java.time.LocalDateTime` 
    from String "2022-04-05T05:00:00.000 00:00": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2022-04-05T05:00:00.000 00:00' 
could not be parsed, unparsed text found at index 23
         at [Source: (String)"{"date":"2022-04-05T05:00:00.000 00:00"}"; line: 1, column: 9]

I am receiving this error by reproducing this like that:

@PostConstruct
public void customDeserializeTest() {
    String content =
        "{\"date\":\"2022-04-05T05:00:00.000 00:00\"}";
    try {
        CustomLocalDataTime customLocalDataTime = objectMapper.readValue(content, CustomLocalDataTime.class);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

I've tried also to add: com.fasterxml.jackson.databind.annotation.

@JsonDeserialize(using = LocalDateTimeDeserializer.class)

but that also does not work.

Thank you very much in advance for any guidance.

CodePudding user response:

Wrong data type

As others commented, you are using the wrong data types.

The LocalDateTime class purposely lacks any concept of time zone or offset-from-UTC. So this class cannot represent a moment, a specific point on the timeline. This class represents only a date and time-of-day, but we have no idea whether that date and time-of-day is intended for Tokyo Japan, Toulouse France, or Toledo Ohio US.

So the LocalDateTime class does not fit your inputs.

The string inputs:

  • 2022-04-05T05:00:00.000 00:00
  • 2022-04-05T05:00:00.000Z

… both represent a moment as seen in UTC, with an offset from UTC of zero hours-minutes-seconds. The Z on the end of the second one is a standard ISO 8601 abbreviation of 00:00, and is pronounced “Zulu”.

Instant & OffsetDateTime

You can parse both such inputs as Instant objects or as more flexible OffsetDateTime objects.

These input strings use standard ISO 8601 formats. The java.time classes use these formats by default when parsing/generating. So no need to specify a formatting pattern.

Instant instant = Instant.parse( "2022-04-05T05:00:00.000 00:00" ) ;
Instant instant2 = Instant.parse( "2022-04-05T05:00:00.000Z" ) ;

OffsetDateTime odt = OffsetDateTime.parse( "2022-04-05T05:00:00.000 00:00" ) ;
OffsetDateTime odt2 = OffsetDateTime.parse( "2022-04-05T05:00:00.000Z" ) ;

See this code run live at IdeOne.com.

instant: 2022-04-05T05:00:00Z
instant2: 2022-04-05T05:00:00Z
odt: 2022-04-05T05:00Z
odt2: 2022-04-05T05:00Z

One Comment mentioned using ZonedDateTime. That would be ill-advised. Time zones have names in format of Continent/Region such as Europe/Paris or Pacific/Auckland. Your inputs have only offsets, not time zones. So ZonedDateTime would be misleading and confusing here.

An offset is merely a number of hours-minutes-seconds ahead or behind the prime meridian of UTC. A time zone is much more. A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region.

  • Related