10

在 Java 8 中,下面的代码将“18”解析为“0018”而不是“2018”。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/y");
return LocalDate.parse(date, formatter);

输入日期是“01/05/18”。

1)为什么结果是“0018”?不DateTimeFormatter遵循 80-20 规则?

2)如何控制 SimpleDateFormat 解析为 19xx 或 20xx?讲到SimpleDateFormat.set2DigitYearStart(Date)可以用来修年。有没有类似的东西DateTimeFormatter

我希望“M/d/y”能够解析 2 位和 4 位数字年份。

“M/d/yy”抛出 4 位数年份的异常并将“01/05/97”解析为“2097-01-05”。理想情况下,这应该被解析为“1997-01-05”。

"M/d/yyyy" 抛出 2 位数年份的异常。

4

2 回答 2

24

没有一个字符串yoru可以让您同时解析两位数和四位数的年份。但是,您可以在格式模式字符串中使用可选部分来指定可能存在两位数或四位数字的年份:

public static LocalDate parseDateString(CharSequence date) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/[uuuu][uu]");
    return LocalDate.parse(date, formatter);
}

试试看:

    System.out.println(parseDateString("01/05/18"));
    System.out.println(parseDateString("01/06/2018"));

这打印:

2018-01-05
2018-01-06

在格式模式字符串中,您需要将四位数年份放在首位。使用相反的顺序,当试图解析一个四位数的年份时,格式化程序将解析两位数,确定到目前为止它是成功的,然后在两位数之后抱怨未解析的文本。

如果您想更精确地控制两位数年份的解释方式:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("M/d/")
            .optionalStart()
            .appendPattern("uuuu")
            .optionalEnd()
            .optionalStart()
            .appendValueReduced(ChronoField.YEAR, 2, 2, 1920)
            .optionalEnd()
            .toFormatter();

在上述方法中使用此格式化程序让我们尝试:

    System.out.println(parseDateString("01/05/22"));

这打印:

1922-01-05

以 1920 为基数(如我的示例代码中所示)将导致两位数的年份结束在 1920 到 2019 的区间内。根据您的要求调整值。

于 2018-01-09T09:38:20.350 回答
0

将您的格式化程序字符串更改为“M/d/yy”

于 2018-01-08T18:34:02.737 回答