8368825: Use switch expression for DateTimeFormatterBuilder pattern character lookup

Reviewed-by: rriggs, naoto, scolebourne
This commit is contained in:
Shaojin Wen 2025-10-02 13:32:09 +00:00
parent 56baf64ada
commit 2c7f7380ea

View File

@ -1937,7 +1937,7 @@ public final class DateTimeFormatterBuilder {
padNext(pad); // pad and continue parsing
}
// main rules
TemporalField field = FIELD_MAP.get(cur);
TemporalField field = getField(cur);
if (field != null) {
parseField(cur, count, field);
} else if (cur == 'z') {
@ -2185,48 +2185,55 @@ public final class DateTimeFormatterBuilder {
}
}
/** Map of letters to fields. */
private static final Map<Character, TemporalField> FIELD_MAP = new HashMap<>();
static {
/**
* Returns the TemporalField for the given pattern character.
*
* @param ch the pattern character
* @return the TemporalField for the given pattern character, or null if not applicable
*/
private static TemporalField getField(char ch) {
// SDF = SimpleDateFormat
FIELD_MAP.put('G', ChronoField.ERA); // SDF, LDML (different to both for 1/2 chars)
FIELD_MAP.put('y', ChronoField.YEAR_OF_ERA); // SDF, LDML
FIELD_MAP.put('u', ChronoField.YEAR); // LDML (different in SDF)
FIELD_MAP.put('Q', IsoFields.QUARTER_OF_YEAR); // LDML (removed quarter from 310)
FIELD_MAP.put('q', IsoFields.QUARTER_OF_YEAR); // LDML (stand-alone)
FIELD_MAP.put('M', ChronoField.MONTH_OF_YEAR); // SDF, LDML
FIELD_MAP.put('L', ChronoField.MONTH_OF_YEAR); // SDF, LDML (stand-alone)
FIELD_MAP.put('D', ChronoField.DAY_OF_YEAR); // SDF, LDML
FIELD_MAP.put('d', ChronoField.DAY_OF_MONTH); // SDF, LDML
FIELD_MAP.put('F', ChronoField.ALIGNED_WEEK_OF_MONTH); // SDF, LDML
FIELD_MAP.put('E', ChronoField.DAY_OF_WEEK); // SDF, LDML (different to both for 1/2 chars)
FIELD_MAP.put('c', ChronoField.DAY_OF_WEEK); // LDML (stand-alone)
FIELD_MAP.put('e', ChronoField.DAY_OF_WEEK); // LDML (needs localized week number)
FIELD_MAP.put('a', ChronoField.AMPM_OF_DAY); // SDF, LDML
FIELD_MAP.put('H', ChronoField.HOUR_OF_DAY); // SDF, LDML
FIELD_MAP.put('k', ChronoField.CLOCK_HOUR_OF_DAY); // SDF, LDML
FIELD_MAP.put('K', ChronoField.HOUR_OF_AMPM); // SDF, LDML
FIELD_MAP.put('h', ChronoField.CLOCK_HOUR_OF_AMPM); // SDF, LDML
FIELD_MAP.put('m', ChronoField.MINUTE_OF_HOUR); // SDF, LDML
FIELD_MAP.put('s', ChronoField.SECOND_OF_MINUTE); // SDF, LDML
FIELD_MAP.put('S', ChronoField.NANO_OF_SECOND); // LDML (SDF uses milli-of-second number)
FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY); // LDML
FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND); // 310 (proposed for LDML)
FIELD_MAP.put('N', ChronoField.NANO_OF_DAY); // 310 (proposed for LDML)
FIELD_MAP.put('g', JulianFields.MODIFIED_JULIAN_DAY);
// 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
// 310 - Z - matches SimpleDateFormat and LDML
// 310 - V - time-zone id, matches LDML
// 310 - v - general timezone names, not matching exactly with LDML because LDML specify to fall back
// to 'VVVV' if general-nonlocation unavailable but here it's not falling back because of lack of data
// 310 - p - prefix for padding
// 310 - X - matches LDML, almost matches SDF for 1, exact match 2&3, extended 4&5
// 310 - x - matches LDML
// 310 - w, W, and Y are localized forms matching LDML
// LDML - B - day periods
// LDML - U - cycle year name, not supported by 310 yet
// LDML - l - deprecated
// LDML - j - not relevant
return switch (ch) {
case 'G' -> ChronoField.ERA; // SDF, LDML (different to both for 1/2 chars)
case 'y' -> ChronoField.YEAR_OF_ERA; // SDF, LDML
case 'u' -> ChronoField.YEAR; // LDML (different in SDF)
case 'Q' -> IsoFields.QUARTER_OF_YEAR; // LDML (removed quarter from 310)
case 'q' -> IsoFields.QUARTER_OF_YEAR; // LDML (stand-alone)
case 'M' -> ChronoField.MONTH_OF_YEAR; // SDF, LDML
case 'L' -> ChronoField.MONTH_OF_YEAR; // SDF, LDML (stand-alone)
case 'D' -> ChronoField.DAY_OF_YEAR; // SDF, LDML
case 'd' -> ChronoField.DAY_OF_MONTH; // SDF, LDML
case 'F' -> ChronoField.ALIGNED_WEEK_OF_MONTH; // SDF, LDML
case 'E' -> ChronoField.DAY_OF_WEEK; // SDF, LDML (different to both for 1/2 chars)
case 'c' -> ChronoField.DAY_OF_WEEK; // LDML (stand-alone)
case 'e' -> ChronoField.DAY_OF_WEEK; // LDML (needs localized week number)
case 'a' -> ChronoField.AMPM_OF_DAY; // SDF, LDML
case 'H' -> ChronoField.HOUR_OF_DAY; // SDF, LDML
case 'k' -> ChronoField.CLOCK_HOUR_OF_DAY; // SDF, LDML
case 'K' -> ChronoField.HOUR_OF_AMPM; // SDF, LDML
case 'h' -> ChronoField.CLOCK_HOUR_OF_AMPM; // SDF, LDML
case 'm' -> ChronoField.MINUTE_OF_HOUR; // SDF, LDML
case 's' -> ChronoField.SECOND_OF_MINUTE; // SDF, LDML
case 'S' -> ChronoField.NANO_OF_SECOND; // LDML (SDF uses milli-of-second number)
case 'A' -> ChronoField.MILLI_OF_DAY; // LDML
case 'n' -> ChronoField.NANO_OF_SECOND; // 310 (proposed for LDML)
case 'N' -> ChronoField.NANO_OF_DAY; // 310 (proposed for LDML)
case 'g' -> JulianFields.MODIFIED_JULIAN_DAY;
default -> null;
// 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
// 310 - Z - matches SimpleDateFormat and LDML
// 310 - V - time-zone id, matches LDML
// 310 - v - general timezone names, not matching exactly with LDML because LDML specify to fall back
// to 'VVVV' if general-nonlocation unavailable but here it's not falling back because of lack of data
// 310 - p - prefix for padding
// 310 - X - matches LDML, almost matches SDF for 1, exact match 2&3, extended 4&5
// 310 - x - matches LDML
// 310 - w, W, and Y are localized forms matching LDML
// LDML - B - day periods
// LDML - U - cycle year name, not supported by 310 yet
// LDML - l - deprecated
// LDML - j - not relevant
};
}
//-----------------------------------------------------------------------