ISO-8601 日期正好是 0 毫秒时应该是什么样子的?

What should an ISO-8601 date look like at exactly 0 milliseconds?

提问人:braveterry 提问时间:10/3/2023 更新时间:10/3/2023 访问量:70

问:

我正在调用一个使用 ISO-8601 格式化日期的 Web 服务(据我所知)。

这是我使用解析日期的模式(我使用 Jackson 来反序列化响应):

yyyy-MM-dd'T'HH:mm:ss.SSS'Z'

大多数情况下,服务返回的日期如下所示:

2022-08-19T22:48:17.228Z

但是,该服务偶尔会返回如下日期:

2023-09-12T00:18:25Z

我认为当毫秒数正好为 0 时会发生这种情况。

这是 ISO-8601 日期的预期行为,还是服务正在做一些奇怪的事情?

java 日期时间 杰克逊 ISO8601

评论

0赞 Jorn 10/3/2023
我在 javadoc 中没有看到普通格式化程序会这样做的指示。也许它被编码到默认的 Jackson 序列化器中?
0赞 Or4ng3h4t 10/3/2023
杰克逊立刻让我去“嘿”
1赞 Mike 'Pomax' Kamermans 10/3/2023
根据规范,十进制分数是完全可选的,但必须“达成一致”,因此无论您从哪里提取此数据(如果它符合规范),都应该在某处有关于此行为的文档。(更有趣的是,在“最小时间”单位上允许使用十进制分数,因此半分钟可能是,这在 ISO-8601 日期中是完全有效的时间)。所以有两种可能性:要么 Jackson 解析错误(在这种情况下,用一个小测试应用程序验证),要么不是,是时候寻找 API 文档了。T00:01,5
0赞 Anonymous 10/4/2023
Instant.parse()分析两个示例,带和不带小数。我原以为 jackson-modules-java8 也会这样做,但如果没有,您始终可以使用提到的 .Instant.pares()

答:

1赞 Or4ng3h4t 10/3/2023 #1

此配置文件未指定可以使用多少位数字来表示 秒的小数点。采用标准,允许 秒的小数分之一必须同时指定最小位数 (大于或等于 1 的数字)和 位数(最大值可以表示为“无限”)。

这意味着服务使用的“掩码”将毫秒的第 3 位数字视为可选,当它为 0 时,它将完全隐藏该值。

解决方法是检查日期的长度并在最后一个字符之前添加一个 0(假设它始终是 Z)

-1赞 Reilas 10/3/2023 #2

"...ISO-8601 日期正好是 0 毫秒时应该是什么样子的?..."

可以使用 Date 类,该类具有毫秒构造函数方法

SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
out.println(f.format(new Date(0)));
1969-12-31T19:00:00.000Z

"...该服务偶尔会返回如下日期:

2023-09-12T00:18:25Z

我认为当毫秒数正好为 0 时会发生这种情况。..."

不,这是一个有效的日期和时间。
时间为 0 – 23,其中 0 表示凌晨 12 点

"...这是 ISO-8601 日期的预期行为,还是服务正在做一些奇怪的事情?..."

责任将归咎于服务,ISO 8601 只是一个符号或代码。