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

Posted

技术标签:

【中文标题】我无法将 \'2017-04-04T08:04+0000\' 解析为 OffsetDateTime【英文标题】:I haven't been able to parse '2017-04-04T08:04+0000' into an OffsetDateTime我无法将 '2017-04-04T08:04+0000' 解析为 OffsetDateTime 【发布时间】:2021-05-12 04:03:15 【问题描述】:

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

【问题讨论】:

您创建了一个具有自定义格式的日期格式化程序,但您最终没有使用它。使用formatter 而不是DateTimeFormatter.ISO_OFFSET_DATE_TIME 使用格式"uuuu-MM-dd'T'HH:mmX" 谢谢,@Andreas 我认为你的格式有效,我也尝试过使用'X's "uuuu-MM-dd'T'HH:mm[XXXXX][XXXX][X] " 这也有效 我无法重现。在我的 Java 8 和我的 Java 11 上,您的格式化程序都会解析 2017-04-04T08:04+0000 【参考方案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] 即可解决问题。)

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

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

【讨论】:

以上是关于我无法将 '2017-04-04T08:04+0000' 解析为 OffsetDateTime的主要内容,如果未能解决你的问题,请参考以下文章

偏移 25 处无法解析的日期

Java:无法将给定的对象格式化为日期

如何使用 c# 将 1606813200000 转换为 2020-12-01T09:00:00.000Z [重复]

Lodash - 如何从嵌套的json中一次只选择一项?

为啥我无法解析这种日期格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ?

js将"2018-08-15T08:04:52.000+0000"这种格式的时间转化为正常格式2019-08-15 15:02:07