代码之家  ›  专栏  ›  技术社区  ›  Jesse Zhuang

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

  •  12
  • Jesse Zhuang  · 技术社区  · 6 年前

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

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

    输入日期为“2018年5月1日”。

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

    2) How to control SimpleDateFormat parse to 19xx or 20xx? 谈论过 SimpleDateFormat.set2DigitYearStart(Date) 可用于确定年份。有没有类似的东西 日期时间格式 ?

    我希望“M/d/y”可以解析2位数和4位数的年份。

    “M/d/yy”引发4位数年份的异常,并将“1997年5月1日”解析为“2097-01-05”。理想情况下,应将其解析为“1997-01-05”。

    “年月日”引发2位数年份的异常。

    2 回复  |  直到 4 年前
        1
  •  26
  •   Anonymous    6 年前

    没有一个字符串 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年之间结束。根据您的要求调整值。

        2
  •  0
  •   Vishal Raja    6 年前

    将格式化程序字符串更改为 “年月日”