Java 我没有';无法解析';2017-04-04T08:04+;0000和x27;进入一个偏移日期时间

Java 我没有';无法解析';2017-04-04T08:04+;0000和x27;进入一个偏移日期时间,java,simpledateformat,date-formatting,dateformatter,isodate,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.s

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

公共类OffsetDateTimeDeserializer
扩展JsonDeserializer
{
私有最终DateTimeFormatter formatter=模式的DateTimeFormatter.(“uuu-MM-dd'T'HH:MM[XXX][XXXX]”);
@凌驾
public OffsetDateTime反序列化(最终JsonParser解析器,
最终反序列化(上下文)
抛出IOException
{
格式化程序withZone(地区名称(“GMT”));
返回OffsetDateTime.parse(parser.readValueAs(String.class),格式化程序);
}
}
只有两个小写xx表示不带冒号的偏移量 当偏移量零表示为
+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版本有一个bug,其中三个
    XXX
    只解析了
    +00
    (小时数),没有解析最后一个
    00
    ,之后
    XXXX
    什么都做不了。这不是我听说过的bug,所以纯粹是猜测,也不太可能。如果这是问题,只需交换
    [XXX]
    [XXXX]
    应该可以补救。)
Edit:您知道我想要以与字符串相同的格式对其进行反序列化,只需将其序列化并比较两个字符串并查看它们是否相等吗?

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

  • 您使用自定义格式创建了一个日期格式化程序,但最终没有使用它。使用
    formatter
    而不是
    DateTimeFormatter.ISO\u OFFSET\u DATE\u TIME
    。使用格式
    “uuu-MM-dd'T'HH:mmX”
    谢谢,@Andreas我认为你的格式有效,我也尝试了这个方法,玩了“X”uuuu-MM-dd'T'HH:MM[XXXXX][X]”,它同样有效,我无法复制。在my Java 8和my Java 11上,格式化程序都解析
    2017-04-04T08:04+0000
        String valueAsString = "2017-04-04T08:04+0000";
        OffsetDateTime deserialized = OffsetDateTime.parse( valueAsString, formatter );
        System.out.println( deserialized );