web-dev-qa-db-ja.com

Java 8 DateTimeFormatter 2桁の年18が2018ではなく0018に解析されましたか?

Java 8の場合、以下のコードは「18」を「2018」ではなく「0018」年に解析します。

_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桁の年の例外をスローします。

9
Jesse Zhuang

2桁と4桁の両方の年を解析できるyまたはuの単一の文字列はありません。ただし、フォーマットパターン文字列でオプションの部分を使用して、2桁または4桁の年が存在する可能性があることを指定できます。

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

フォーマットパターン文字列では、最初に4桁の年を入力する必要があります。逆の順序で、4桁の年を解析しようとすると、フォーマッタは2桁を解析し、これまでに成功したと判断してから、2桁以降の未解析のテキストについて文句を言います。

2桁の年の解釈をより正確に制御したい場合:

    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桁の年になります。要件に合わせて値を調整してください。

16
Ole V.V.

Formatter文字列を「M/d/yy」に変更します

0
Vishal Raja