JSR310 Year.parse() 抛出值 < 1000 的 DateTimeParseException
JSR310 Year.parse() throws DateTimeParseException with values < 1000
我正在尝试使用 java.time.Year.parse()
解析 0 到 1000 范围内的年份字符串值,但是解析失败 java.time.format.DateTimeParseException: Text '999' could not be parsed at index 0
。
Year.parse
的 javadoc 指出:
Obtains an instance of Year from a text string such as 2007.
The string must represent a valid year. Years outside the range 0000 to 9999
must be prefixed by the plus or minus symbol.
重现此问题的示例测试:
@Test
public void parse_year() {
for (int i = 2000; i >= 0; i--) {
System.out.println("Parsing year: " + i);
Year.parse(String.valueOf(i));
}
}
999
年时测试抛出异常:
Parsing year: 1003
Parsing year: 1002
Parsing year: 1001
Parsing year: 1000
Parsing year: 999
java.time.format.DateTimeParseException: Text '999' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.Year.parse(Year.java:292)
at java.time.Year.parse(Year.java:277)
[...]
我做错了什么?
需要补到4位
Year.parse(String.format("%04d", i));
Parsing year: 2000
Parsing year: ....
Parsing year: 4
Parsing year: 3
Parsing year: 2
Parsing year: 1
Parsing year: 0
如果你想在第 0 年之前解析,你可以使用
Year.parse("-0001");
您在 java.time 中发现了一个非常奇怪的不一致之处。
首先,对于你观察到的行为,我认为是有道理的。 java.time 的 classes 通常解析最常见的 ISO 8601 格式变体。一年的 ISO 8601 格式是(来自维基百科,底部的 link):
ISO 8601 prescribes, as a minimum, a four-digit year [YYYY] to avoid
the year 2000 problem. It therefore represents years from 0000 to
9999, year 0000 being equal to 1 BC and all others AD.
所以即使你引用的 Year.parse()
的文档不是很清楚,至少 4 位数字的要求是从 ISO 8601 中提取的,当然是故意的。
java.time 的其他 class 有相同的要求。
LocalDate.parse("999-12-31");
Exception in thread "main" java.time.format.DateTimeParseException: Text '999-12-31' could not be parsed at index 0
到目前为止 java.time 是一致的。
当我尝试 Year.toString
方法时,惊喜来了。 java.time classes 的 toString
方法通常也打印 ISO 8601 格式。
System.out.println(Year.of(999).toString());
输出为:
999
所以 Year
打印出一种 不 符合 ISO 8601 的格式,更令人惊讶的是,它无法使用其单参数 parse
方法。这是我没想到的 java.time class.
如果要解析少于 4 位数字的年份,只需使用格式化程序:
DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("u");
System.out.println(Year.parse("999", yearFormatter));
System.out.println(Year.parse("0", yearFormatter));
999
0
Link
我正在尝试使用 java.time.Year.parse()
解析 0 到 1000 范围内的年份字符串值,但是解析失败 java.time.format.DateTimeParseException: Text '999' could not be parsed at index 0
。
Year.parse
的 javadoc 指出:
Obtains an instance of Year from a text string such as 2007.
The string must represent a valid year. Years outside the range 0000 to 9999
must be prefixed by the plus or minus symbol.
重现此问题的示例测试:
@Test
public void parse_year() {
for (int i = 2000; i >= 0; i--) {
System.out.println("Parsing year: " + i);
Year.parse(String.valueOf(i));
}
}
999
年时测试抛出异常:
Parsing year: 1003
Parsing year: 1002
Parsing year: 1001
Parsing year: 1000
Parsing year: 999
java.time.format.DateTimeParseException: Text '999' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.Year.parse(Year.java:292)
at java.time.Year.parse(Year.java:277)
[...]
我做错了什么?
需要补到4位
Year.parse(String.format("%04d", i));
Parsing year: 2000
Parsing year: ....
Parsing year: 4
Parsing year: 3
Parsing year: 2
Parsing year: 1
Parsing year: 0
如果你想在第 0 年之前解析,你可以使用
Year.parse("-0001");
您在 java.time 中发现了一个非常奇怪的不一致之处。
首先,对于你观察到的行为,我认为是有道理的。 java.time 的 classes 通常解析最常见的 ISO 8601 格式变体。一年的 ISO 8601 格式是(来自维基百科,底部的 link):
ISO 8601 prescribes, as a minimum, a four-digit year [YYYY] to avoid the year 2000 problem. It therefore represents years from 0000 to 9999, year 0000 being equal to 1 BC and all others AD.
所以即使你引用的 Year.parse()
的文档不是很清楚,至少 4 位数字的要求是从 ISO 8601 中提取的,当然是故意的。
java.time 的其他 class 有相同的要求。
LocalDate.parse("999-12-31");
Exception in thread "main" java.time.format.DateTimeParseException: Text '999-12-31' could not be parsed at index 0
到目前为止 java.time 是一致的。
当我尝试 Year.toString
方法时,惊喜来了。 java.time classes 的 toString
方法通常也打印 ISO 8601 格式。
System.out.println(Year.of(999).toString());
输出为:
999
所以 Year
打印出一种 不 符合 ISO 8601 的格式,更令人惊讶的是,它无法使用其单参数 parse
方法。这是我没想到的 java.time class.
如果要解析少于 4 位数字的年份,只需使用格式化程序:
DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("u");
System.out.println(Year.parse("999", yearFormatter));
System.out.println(Year.parse("0", yearFormatter));
999 0
Link