Весенняя загрузка: десериализация даты и времени JSON с часовым поясом в LocalDateTime

Я использую Java 11, Spring Boot 2.2.6.RELEASE. Как я могу десериализовать "2019-10-21T13: 00: 00 + 02: 00" в LocalDateTime?

Пробовал пока:

        @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  @DateTimeFormat(iso = ISO.DATE_TIME)
  @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ")
  private LocalDateTime startTime;

Но я получаю следующую ошибку:

      2021-02-19 07:45:41.402  WARN 801117 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.time.LocalDateTime` from String "2019-10-21T13:00:00+02:00": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2019-10-21T13:00:00+02:00' could not be parsed, unparsed text found at index 19; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDateTime` from String "2019-10-21T13:00:00+02:00": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2019-10-21T13:00:00+02:00' could not be parsed, unparsed text found at index 19
 at [Source: (PushbackInputStream); line: 2, column: 18] (through reference chain: example.app.dto.DtoRequest["startTime"])]

1 ответ

В вашем коде есть две проблемы:

1. Использование неправильного типа

Невозможно десериализовать значение типа java.time.LocalDateTime from String «2019-10-21T13: 00: 00 + 02: 00»: не удалось десериализовать java.time.LocalDateTime: (java.time.format.DateTimeParseException)Text '2019-10-21T13:00:00+02:00'не удалось проанализировать, не проанализированный текст найден по индексу 19

Если вы проанализируете сообщение об ошибке, вы обнаружите, что оно явно говорит вам о проблеме с индексом 19.

      2019-10-21T13:00:00+02:00
// index 19 ---->  ^  

И проблема в том, что LocalDateTimeне поддерживает часовой пояс. Ниже приведен обзор типов java.time, и вы можете видеть, что тип, который соответствует вашей строке даты и времени, OffsetDateTime потому что он имеет смещение зоны +02:00 часы.

Измените свою декларацию следующим образом:

      private OffsetDateTime startTime;

2. Использование неправильного формата

Вам нужно использовать XXX для части смещения, т.е. ваш формат должен быть uuuu-MM-dd'T'HH:m:ssXXX. Если вы хотите придерживаться Z, вам нужно использовать ZZZZZ. Проверьте страницу документации <tcode id="398275"></tcode> Больше подробностей.

Демо:

      import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2019-10-21T13:00:00+02:00";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:m:ssXXX");
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime, dtf);
        System.out.println(odt);
    }
}

Выход:

      2019-10-21T13:00+02:00

Узнайте больше о современном API даты и времени из Trail: Date Time .

Другие вопросы по тегам