我无法将“2017-04-04T08:04+0000”解析为 OffsetDateTime

I haven't been able to parse '2017-04-04T08:04+0000' into an OffsetDateTime

我创建了这个反序列化器以在集中式自定义对象映射器 bean 中进行管理,它工作正常,但我无法反序列化以这种格式出现的日期 '2017-04-04T08:04 +0000' 转换为正确的 OffsetDateTime 格式 - 出现以下异常:

Text '2017-04-04T08:04+0000' could not be parsed, unparsed text found at index 19 (through reference chain: earth.green.integration_models.sh.Prediction$PredictionBuilder["created"])

我在 Internet 上搜索了很多格式,其中 none 有效,所以如果你们知道我可以使用哪种格式反序列化此日期,将会非常有帮助。


public class OffsetDateTimeDeserializer
      extends JsonDeserializer<OffsetDateTime>
{
    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm[XXX][XXXX]" );


    @Override
    public OffsetDateTime deserialize( final JsonParser parser,
                                       final DeserializationContext context )
          throws IOException
    {
        formatter.withZone( ZoneId.of( "GMT") );
        return OffsetDateTime.parse( parser.readValueAs( String.class ), formatter );
    }
}

只有两个小写 xx 用于不带冒号的偏移量

private final DateTimeFormatter formatter
        = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mmxx" );    

当偏移量零被指定为 +0000 而不是 Z 时,使用小写字母 xx

示范:

    String valueAsString = "2017-04-04T08:04+0000";
    OffsetDateTime deserialized = OffsetDateTime.parse( valueAsString, formatter );
    System.out.println( deserialized );

这输出:

2017-04-04T08:04Z

您的代码出了什么问题? 来自文档:

Offset X and x: This formats the offset based on the number of pattern letters. One letter outputs just the hour, such as '+01', unless the minute is non-zero in which case the minute is also output, such as '+0130'. Two letters outputs the hour and minute, without a colon, such as '+0130'. Three letters outputs the hour and minute, with a colon, such as '+01:30'. Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'. Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'. …

根据这个 XXX 应该尝试用冒号解析像 +00:00 这样的偏移量,但失败了,因为解析的字符串中的偏移量中没有冒号。接下来 XXXX 应该尝试 +0000+000000 因为秒数是可选的,所以应该会成功。它也在我的电脑上做了。所以我能想到的解释包括:

  • 您 运行 的代码与您在问题中发布的代码并不完全相同。我相信可能你的问题的第一个版本包含产生异常的代码,而你更新代码后没有更新异常消息。
  • (可能您的 Java 版本有一个错误,其中三个 XXX 只解析了 +00(小时),而最后一个 00 未解析,之后 XXXX 什么也做不了。这不是我听说过的错误,所以纯粹是猜测,不太可能。如果这是问题所在,只需交换 [XXX][XXXX] 就可以解决。 )

编辑:你知道我想让它以与字符串相同的格式反序列化吗,只是为了序列化回来并比较两个字符串,看看它们是否相等?

  1. 以相反的方式进行测试:序列化一个 OffsetDateTime,反序列化它并检查两个 OffsetDateTime 对象是否相等。
  2. 如果您坚持,请在格式模式字符串中使用小写 xx。这可以防止将零偏移量呈现为 Z。这意味着 2017-04-04T08:04+0000 将被打印回来,与您开始时相同的字符串。