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

时间:2021-05-12 04:03:15

标签: java simpledateformat date-formatting dateformatter isodate

我创建了这个反序列化器,在一个集中的自定义对象映射器 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"])

我在互联网上搜索了很多格式,但都没有奏效,所以如果你们中的任何人知道我可以使用哪种格式来反序列化这个日期,将会非常有帮助。


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 );
    }
}

1 个答案:

答案 0 :(得分:1)

只有两个小写的 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

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

<块引用>

偏移量 X 和 x: 这根据模式字母的数量格式化偏移量。一个字母只输出小时,例如“+01”, 除非分钟不为零,在这种情况下,分钟也被输出, 例如“+0130”。两个字母输出小时和分钟,没有 冒号,例如“+0130”。三个字母输出小时和分钟, 带有冒号,例如“+01:30”。四个字母输出小时和 分钟和可选的秒,没有冒号,例如“+013015”。五 字母输出小时和分钟以及可选的秒,带冒号, 例如“+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 将被打印回来,与您开始时的字符串相同。