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桁の年の例外をスローします。
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桁の年になります。要件に合わせて値を調整してください。
Formatter文字列を「M/d/yy」に変更します