java.time.Instant - 解析大日期时出错

java.time.Instant - error while parsing a huge date

提问人:Sogawa-sps 提问时间:4/15/2023 更新时间:4/16/2023 访问量:149

问:

我正在尝试使用 Instant.parse 方法解析一个非常大的日期(但仍然比 Instant.MAX 少得多),但出现错误。

String input = "78000000-01-01T00:00:00Z";
Instant instant = Instant.parse(input);

例外:

Exception in thread "main" java.time.format.DateTimeParseException: Text '78000000-01-01T00:00:00Z' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2106)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2008)
at java.base/java.time.Instant.parse(Instant.java:399)

BC 日期“-78000000-01-01T00:00:00Z”解析正常。

我在 Java :)中发现了错误吗?

java java-time java.time.instant

评论

7赞 user16320675 4/15/2023
不,不是错误 - 如上所述,正在使用 ISO-8601;它要求:“为了表示 0000 之前或 9999 之后的年份,该标准还允许扩展年份表示......扩展的年份表示形式 [±YYYYY] ...,并且必须以 + 或 − 号为前缀“ - 已发布的输入字符串缺少符号parse()+
0赞 Abhijit Sarkar 4/16/2023
"我在 Java 中发现了一个错误吗“ 每当你问这个问题时,答案几乎总是否定的。

答:

10赞 5 revs, 3 users 81%user16320675 #1

功能,而不是错误

不,这不是错误 - 正在按规定工作!

来自以下文档parse()

使用 DateTimeFormatter.ISO_INSTANT 进行分析

ISO_INSTANT

返回一个不可变的格式化程序,能够格式化和解析 ISO-8601 即时格式

ISO_INSTANTISO_LOCAL_DATE。最后一个说:ISO_OFFSET_DATE_TIMEISO_LOCAL_DATE_TIME

  • 一年的四位数或更多。0000 到 9999 范围内的年份
    将预先填充为零,以确保四位数字。超出该
    范围的年份将具有前缀的正号或负号。

这意味着要解析的年份也必须遵守上述格式。

最后,来自维基百科的ISO-8601():

为了表示 0000 之前或 9999 之后的年份,该标准还允许扩展年份表示......扩展的年份表示形式 [±YYYYY] 必须具有商定的超出四位数最小值的额外年份数字数,并且必须以 + 或 − 号为前缀

强调我的


输入字符串缺少该符号,而正确以符号开头。"78000000-01-01T00:00:00Z"+"-78000000-01-01T00:00:00Z"-

分析输入时没有错误。"+78000000-01-01T00:00:00Z"


提示:您可以通过格式化测试日期/时间/...在解析之前。
例如:

var test = Instant.from(OffsetDateTime.of(78000000, 1, 1, 0, 0, 0, 0,ZoneOffset.UTC));
System.out.println(test.toString());  // or using any relevant formatter

输出:

+78000000-01-01T00:00:00Z

评论

0赞 Sogawa-sps 4/16/2023
谢谢你@user16320675,现在很清楚了。顺便说一句,我想知道为什么决定不允许 0000..9999 范围内的日期使用“+”(比如“+1300-01-01T00:00:00Z”是不可解析的),从我的角度来看,这更有意义。但事实就是如此。