基于此Java日期时间-OffsetDateTime.format() Examples文章和DateTimeFormatter的官方文档,我希望将OffsetDateTime序列化为2011-12-03T10:15:30+00:00
,其中offset为offset {{1} },因为它是UTC。
我无法使OffsetDateTime具有偏移量进行渲染,它始终仅以'Z'Zulu进行渲染。我在做什么错了?
这是Spring Boot 2.0.0.RELEASE,正如您在屏幕快照中所看到的,我在类路径上具有以下模块并向objectMapper注册,尽管我认为这不是相对的,因为这个问题似乎是直接使用DateTimeFormatter,我的对象映射器只是使用我提供的格式化程序。
它确实有影响,因为正如您在第二个屏幕截图中看到的那样,当我指定+00:00
时,它的确产生了不同的结果。
我在我的application.properties中确实设置了此属性BASIC_ISO_FORMAT
,但是据我所知,这对OffsetDateTime没有影响,它仅支持Java早期版本中的旧Date对象。顺便更改此似乎没有预期的影响。
任何帮助将不胜感激。
使用BASIC_ISO_FORMAT ...确实会产生影响,所以我知道格式化程序正在执行某些操作,但我不清楚为什么ISO_ZONED_DATE_TIME未按预期呈现。
spring.jackson.date-format= com.fasterxml.jackson.databind.util.ISO8601DateFormat
答案 0 :(得分:3)
DateTimeFormatter. ISO_OFFSET_DATE_TIME
的文档告诉您在使用零偏移量(UTC本身)时期望使用Z
而不是+00:00
。
那个医生说:
格式包括:
•ISO_LOCAL_DATE_TIME
•偏移量ID。
跟随第二项offset ID的链接。该页面上显示:
共有三种格式:
•Z-适用于UTC(ISO-8601)
•+ hh:mm或-hh:mm-如果秒为零(ISO-8601)
•+ hh:mm:ss或-hh:mm:ss-如果秒数不为零(不是ISO-8601)
Z
是ISO 8601标准的一部分。任何体面的日期时间库都应该能够使用Z
解析字符串。
如果您坚持使用+00:00
而不是更常见的Z
,则需要指定由Ole V.V链接的the Question中讨论的自定义格式设置模式。
-00:00
自UTC以来的偏移量是-00:00。
您在问题中使用-00:00
是不正确的。 ISO 8601标准明确禁止使用该值。 UTC本身的偏移量为正零,而不是负零:+00:00
。
有RFC 3339宣称自己是ISO 8601的“配置文件”。RFC违反了ISO 8601,允许使用-00:00
,并为其指定了未知偏移量的含义。恕我直言,这是一个非常贫穷和不明智的选择,令人困惑和不必要。 ISO 8601已经解决了未知的偏移:只需完全省略偏移符号即可。
我建议同时避免使用负零和RFC3339。
答案 1 :(得分:2)
您知道,将偏移量零(或Zulu)格式化为Z
应该可以。这是您使用的标准格式ISO 8601的一部分。但是,如果没有,则为:
static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssxxx");
@Override
public void serialize(OffsetDateTime offsetDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
String formattedDate = formatter.format(offsetDateTime);
jsonGenerator.writeString(formattedDate);
}
这将对OffsetDateTime
进行序列化,例如2011-12-03T10:14:30+00:00
(在标准中也允许)。格式模式字符串中的小写字母x
用于格式化偏移量,而对于零偏移量不求助于Z
。
以上是格式化程序的简短直接声明。由于我希望尽可能地依赖更高级别的标准元素,因此我考虑使用更长的变体:
static DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("xxx")
.toFormatter();
这将重用标准库中的ISO_LOCAL_DATE_TIME
。如果您的时间没有几分之一秒,那么输出将是相同的。如果已包含,则将在后一种情况下将其包括在序列化中,就像使用ISO_OFFSET_DATE_TIME
,例如2011-12-03T10:14:30.1234+00:00
一样。