5

我正在尝试使用 解析 0 到 1000 范围内的年份字符串值java.time.Year.parse(),但是解析失败并使用java.time.format.DateTimeParseException: Text '999' could not be parsed at index 0.

状态的javadoc Year.parse

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

2 回答 2

4

需要补到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");
于 2020-05-20T07:36:08.713 回答
2

您在 java.time 中发现了一个非常奇特的不一致。

首先,对于您观察到的行为,我认为这是有道理的。java.time 的类通常解析最常见的 ISO 8601 格式变体。一年的 ISO 8601 格式是(来自维基百科,链接在底部):

ISO 8601 至少规定了一个四位数的年份 [YYYY],以避免出现 2000 年问题。因此,它代表从 0000 到 9999 的年份,0000 年等于 1 BC 和所有其他 AD。

因此,即使Year.parse()您引用的文档不是很清楚,但至少 4 位数字的要求来自 ISO 8601,当然是故意的。

java.time 的其他类具有相同的要求。

    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方法时感到惊讶。toStringjava.time 类的方法一般也打印 ISO 8601 格式。

    System.out.println(Year.of(999).toString());

输出是:

999

因此Year打印出一种符合 ISO 8601 的格式,更令人惊讶的是,它无法使用其单参数parse方法解析回来的格式。这是我从任何 java.time 类中都没有预料到的。

如果要解析少于 4 位的年份,只需使用格式化程序:

    DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("u");
    System.out.println(Year.parse("999", yearFormatter));
    System.out.println(Year.parse("0", yearFormatter));
999
0

关联

于 2020-05-20T19:51:42.147 回答