DateTimeFormatter.ISO_OFFSET_DATE_TIME 未按预期工作

ezt*_*ams 3 datetimeoffset datetime-format spring-boot

基于此 Java 日期时间 - OffsetDateTime.format() 示例文章和DateTimeFormatter 的官方文档,我希望我的 OffsetDateTime 被序列化为自 UTC 以来2011-12-03T10:15:30+00:00偏移量的偏移量+00:00。

我无法让 OffsetDateTime 使用偏移量进行渲染,它总是只使用“Z”祖鲁语进行渲染。我究竟做错了什么?

在此处输入图片说明

这是Spring Boot 2.0.0.RELEASE,正如您在屏幕截图中看到的,我在类路径上有以下模块并注册了 objectMapper,尽管我认为这不是相对的,因为这个问题似乎是直接的使用 DateTimeFormatter,我的对象映射器只是使用我提供的格式化程序。

它确实有影响,因为正如您在第二个屏幕截图中看到的那样,当我指定BASIC_ISO_FORMAT它确实会产生不同的结果。

我确实spring.jackson.date-format= com.fasterxml.jackson.databind.util.ISO8601DateFormat在我的 application.properties 中设置了这个属性,但据我所知,这对 OffsetDateTime 没有影响,它只支持旧版 java 中的遗留 Date 对象。顺便说一下,改变这一点似乎没有预期的影响。

任何帮助,将不胜感激。

使用 ISO_ZONED_DATE_TIME 格式... 使用 ISO_ZONED_DATE_TIME 格式

使用 BASIC_ISO_FORMAT ... 这确实有影响,所以我知道格式化程序正在做某事,我只是不清楚为什么 ISO_ZONED_DATE_TIME 没有按预期呈现。 使用 BASIC_ISO_FORMAT

 this.objectMapper = objectMapperBuilder.build()      
      .setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
      .disable(SerializationFeature.INDENT_OUTPUT)
      .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
      .disable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID);

 SimpleModule simpleModule = new SimpleModule();
 simpleModule.addSerializer(OffsetDateTime.class, new JsonSerializer<OffsetDateTime>() {
        @Override
        public void serialize(OffsetDateTime offsetDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            String formattedDate = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(offsetDateTime);
            jsonGenerator.writeString(formattedDate);
        }
    });
this.objectMapper.registerModule(simpleModule);

OffsetDateTime now = OffsetDateTime.now();
TimeZone defaultTimeZone = TimeZone.getDefault();
ZoneId defautlZoneOffset = ZoneOffset.systemDefault();
String serializedOffsetDateTime = this.objectMapper.writeValueAsString(now);
//returns -> "2018-06-27T11:45:56.035Z"
Run Code Online (Sandbox Code Playgroud)

Bas*_*que 6

功能,而不是错误

的文档DateTimeFormatter. ISO_OFFSET_DATE_TIME告诉您在使用零偏移量(UTC 本身)时期望 aZ而不是 a +00:00。

那个医生说:

格式包括:

• ISO_LOCAL_DATE_TIME

• 偏移ID。

按照第二项的链接,偏移 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 VV 链接的问题中所述

没有这样的事情 -00:00

自 UTC 以来,偏移量为 -00:00。

您-00:00在问题中的使用不正确。ISO 8601 标准明确禁止这样的值。UTC 本身的偏移量是正零,而不是负零:+00:00。

有RFC 3339,其宣称自己是一个ISO 8601的“个人资料”的RFC违反了ISO 8601的允许使用-00:00,并为其分配一个未知的偏移的意义。一个非常糟糕和不明智的选择,恕我直言,令人困惑和不需要。ISO 8601 已经考虑了一个未知的偏移量:只需完全省略偏移量表示法。

我建议避免这种负零的做法和 RFC 3339。