Spring boot: JSON 将带有时区的日期和时间反序列化为 LocalDateTime

Spring boot: JSON deserialize date and time with time zone to 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。使用了错误的类型

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

如果你分析错误信息,你会发现它清楚地告诉你索引 19 有问题。

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

而且,问题是 LocalDateTime 不支持时区。下面给出的是 overview of java.time types,您可以看到与日期时间字符串匹配的类型是 OffsetDateTime,因为它的时区偏移量为 +02:00 小时。

按如下方式更改您的声明:

private OffsetDateTime startTime;

2。使用了错误的格式

您需要使用 XXX 作为偏移部分,即您的格式应为 uuuu-MM-dd'T'HH:m:ssXXX。如果你想坚持Z,你需要使用ZZZZZ。查看 documentation page of DateTimeFormatter 了解更多详情。

演示:

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

Trail: Date Time.

了解有关现代日期时间的更多信息 API

也相关,RFC3339 - Internet 上的日期和时间:时间戳

This document defines a date and time format for use in Internet
protocols that is a profile of the ISO 8601 standard for
representation of dates and times using the Gregorian calendar.