当前位置: 首页 > 知识库问答 >
问题:

用可变的小数秒数反序列化日期的Java日期模式?

葛浩阔
2023-03-14
@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX", timezone = "UTC")
Instant timestamp;

它使用Jackson V2.6.6@JSONFormat注释来反序列化通过网络传输的JSON中的“时间戳”字段。

我所看到的是,当值类似于:

“2017-01-09T21:49:26.70Z”

Caused by: java.time.format.DateTimeParseException: Text '2017-01-09T21:49:26.7Z' could not be parsed at index 19
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) ~[?:1.8.0_65]
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1777) ~[?:1.8.0_65]
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:150) ~[jackson-datatype-jsr310-2.6.6.jar:2.6.6]
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:45) ~[jackson-datatype-jsr310-2.6.6.jar:2.6.6]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[jackson-databind-2.6.6.jar:2.6.6]
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101) ~[jackson-databind-2.6.6.jar:2.6.6]
    at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserialize(SuperSonicBeanDeserializer.java:156) ~[jackson-module-afterburner-2.6.6.jar:2.6.6]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736) ~[jackson-databind-2.6.6.jar:2.6.6]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2764) ~[jackson-databind-2.6.6.jar:2.6.6]

我可以做些什么来修复这个模式,使它在接受小数点后第二位的小数位数方面变得灵活呢?我知道Java数据格式化中有一个宽松的概念:https://docs.oracle.com/javase/8/docs/api/Java/time/format/datetimeformatter.html

但我不确定如何将对象映射器设置为宽松模式。

共有1个答案

柴岳
2023-03-14

只是一个猜测…

我怀疑您可能在Java8的早期版本中遇到了一些Java.time bug。有几个与解析相关的bug,有些在Java8的更新中得到了修复,有些在Java9中得到了修复。

我猜错误文本中的1.8.0_65字符串指的是Java8Update65。目前,Oracle实现处于更新121。

System.out.println ( "Java vendor: " + System.getProperty ( "java.vendor" ) );
System.out.println ( "Java version: " + System.getProperty ( "java.version" ) );

List<String> strings = new ArrayList<> ();
strings.add ( "2017-01-09T21:49:26.7Z" );
strings.add ( "2017-01-09T21:49:26.70Z" );
strings.add ( "2017-01-09T21:49:26.700Z" );
strings.add ( "2017-01-09T21:49:26.7000Z" );
strings.add ( "2017-01-09T21:49:26.70000Z" );

for ( String string : strings ) {
    try {
        Instant instant = Instant.parse ( string );
        System.out.println ( "GOOD - string: " + string + " parsed: " + instant );
    } catch ( DateTimeParseException e ) {
        System.out.println ( "ERROR - Failed to parse string: " + string );
    }
}
System.out.println ( "Done." );
Java vendor: Oracle Corporation
Java version: 1.8.0_121
GOOD - string: 2017-01-09T21:49:26.7Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.70Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.700Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.7000Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.70000Z parsed: 2017-01-09T21:49:26.700Z

您还可以看到相同的代码在ideone.com上运行,运行Oracle实现的Java8 Update121,没有问题。

我也试过你的格式化模式。它适用于.70.700,但不适用于其他。

DateTimeFormatter f = DateTimeFormatter.ofPattern ( "yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX" , Locale.US );
for ( String string : strings ) {
    try {
        OffsetDateTime odt = OffsetDateTime.parse ( string , f );
        System.out.println ( "GOOD - string: " + string + " parsed: " + odt );
    } catch ( DateTimeParseException e ) {
        System.out.println ( "ERROR - Failed to parse string: " + string );
    }
}
System.out.println ( "Done with 'DateTimeFormatter.ofPattern'." );
ERROR - Failed to parse string: 2017-01-09T21:49:26.7Z
GOOD - string: 2017-01-09T21:49:26.70Z parsed: 2017-01-09T21:49:26.700Z
GOOD - string: 2017-01-09T21:49:26.700Z parsed: 2017-01-09T21:49:26.700Z
ERROR - Failed to parse string: 2017-01-09T21:49:26.7000Z
ERROR - Failed to parse string: 2017-01-09T21:49:26.70000Z

仅供参考,字符串的格式如2017-01-09t21:49:26.70z是在ISO 8601标准中定义的。在解析或生成表示日期时间值的字符串时,java.time类默认使用这些标准的ISO 8601格式。

 类似资料:
  • 问题内容: 我正在尝试反序列化具有JavaScript日期的json对象。在对象上调用JSON.stringify时,日期会序列化为未正确反序列化回日期的字符串。我尝试使用带有chrome,IE和FF的本机浏览器实现以及使用jquery来反序列化对象。两者都给出了一些结果。这是代码段: 我希望objDeser.Date是js日期而不是字符串。您可以在此处查看此问题的实际使用情况:http : //

  • 无法从字符串“1979-12-05T08:00Z”反序列化java.util.Date类型的值:无效表示(错误:无法分析日期值“1979-12-05T08:00Z”:无法分析日期“1979-12-05T08:00.000Z”:虽然它似乎符合格式“yyyy-mm-dd't'hh:mm:ss.sss'z'',但分析失败 到目前为止,我试图包含这种依赖关系: 还有: 但没有奏效。

  • 我正在尝试用自定义日期格式序列化和反序列化相当简单的对象: 在执行main方法时,我希望得到类似于: “日期”:“20151117” 20151117 但不幸的是得到了以下几点: {“日期”:“20151117”} 20151117-01-01T00:00:00.000+03:00(年份不正确) 似乎Jackson忽略了对象反序列化的@JSONFORMAT注释,并将字符串视为ISO-8601符号中

  • 奇怪的是下面的测试用例会失败。有人知道为什么吗?

  • 问题内容: 给定以下JSON Date表示形式: 您如何将其反序列化为JavaScript Date类型的形式? 我尝试使用MS AJAX JavaScrioptSerializer,如下所示: 但是,我得到的只是文字字符串日期。 问题答案: 如果您知道该字符串绝对是我更喜欢这样做的日期:

  • 问题内容: 经过4个小时的不间断尝试来解决问题,我决定在这里询问是否有人可以帮助我。 问题是我的Android客户端在尝试反序列化从服务器接收到的数据时抛出“ Unparseable:1302828677828”异常。 我想知道是否可以使用Gson反序列化毫秒格式的日期。 问题答案: 阿方索的评论: 终于我得到了解决方案: