Java 8 Java 8 DateTimeFormatter两位数年份18解析为0018而不是2018?

Java 8 Java 8 DateTimeFormatter两位数年份18解析为0018而不是2018?,java-8,date-format,java-time,date-parsing,y2k,Java 8,Date Format,Java Time,Date Parsing,Y2k,对于Java8,下面的代码将“18”解析为“0018”年,而不是“2018” 输入日期为“01/05/18” 1) 为什么结果是“0018”?DateTimeFormatter是否不遵循80-20规则 2) 讨论了SimpleDateFormat.set2digityearst(日期)可用于确定年份。是否有类似于DateTimeFormatter的功能 我希望“M/d/y”能同时解析2位数和4位数的年份 “M/d/yy”抛出4位数年份的异常,并将“01/05/97”解析为“2097-01-05”

对于Java8,下面的代码将“18”解析为“0018”年,而不是“2018”

输入日期为“01/05/18”

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

2) 讨论了
SimpleDateFormat.set2digityearst(日期)
可用于确定年份。是否有类似于
DateTimeFormatter
的功能

我希望“M/d/y”能同时解析2位数和4位数的年份

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


“M/d/yyyy”引发2位数年份的异常。

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

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

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年之间结束。根据您的要求调整值。

您的意思是:
M/d/yy
,因为您想支持两位数的年份?奇怪的问题。我尝试使用
u
而不是
y
,得到了相同的行为。示例:使用模式“M/d/u”=
0008-01-02
输入“1/2/8”。似乎只有两位数的
uu
yy
2000
的默认世纪相匹配。来自:“年份:字母数决定使用填充的最小字段宽度。如果字母数为2,则使用缩减的两位数形式进行解析…在解析时,这将使用2000的基值进行解析,导致2000到2099(含)范围内的年份。如果字母数小于4(但不是2),…”当然可能是重复的,如果输入中有2位数的年份,则必须在模式中使用2位数符号yy或uu。添加到我希望用“M/d/y”处理2位数和4位数年份的问题。这是我正在寻找的解决方案,特别是
appendValueReduced(ChronoField.year,2,2,1920)
method.
appendValueReduced(ChronoField.YEAR,2,2,LocalDate.now().minusYears(80))
可以用来实现我在问题中提到的80-20规则的行为(使用
SimpleDateFormat.set2DigitYearStart(Date)
)。值得注意的是,如果您想调用
.format()
,结果将是错误的。它将2021年的“202121”;这两种年份模式都是输出。这可能不是期望的!
1922-01-05