Как обрабатывать верхний или нижний регистр в JSR 310?

Если месяц находится в верхнем или нижнем регистре, то есть не в случае с заголовком, DateTimeFormatter не может проанализировать дату. Есть ли простой способ преобразования даты в заголовок или способ сделать форматтера более мягким?

for (String date : "15-JAN-12, 15-Jan-12, 15-jan-12, 15-01-12".split(", ")) {
    try {
        System.out.println(date + " => " + LocalDate.parse(date,
                                     DateTimeFormatter.ofPattern("yy-MMM-dd")));
    } catch (Exception e) {
        System.out.println(date + " => " + e);
    }
}

печатает

15-JAN-12 => java.time.format.DateTimeParseException: Text '15-JAN-12' could not be parsed at index 3
15-Jan-12 => 2015-01-12
15-01-12 => java.time.format.DateTimeParseException: Text '15-01-12' could not be parsed at index 3
15-jan-12 => java.time.format.DateTimeParseException: Text '15-jan-12' could not be parsed at index 3

Ответ 1

DateTimeFormatter по умолчанию строгие и чувствительные к регистру. Используйте DateTimeFormatterBuilder и укажите parseCaseInsensitive() для анализа без учета регистра.

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .parseCaseInsensitive()
    .appendPattern("yy-MMM-dd")
    .toFormatter(Locale.US);

Чтобы иметь возможность анализировать числовые месяцы (т.е. "15-01-12"), вам также необходимо указать parseLenient().

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .parseCaseInsensitive()
    .parseLenient()
    .appendPattern("yy-MMM-dd")
    .toFormatter(Locale.US);

Вы также можете быть более подробным, чтобы указать только месячную часть как нечувствительную к регистру/снисходительность:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendPattern("yy-")
    .parseCaseInsensitive()
    .parseLenient()
    .appendPattern("MMM")
    .parseStrict()
    .parseCaseSensitive()
    .appendPattern("-dd")
    .toFormatter(Locale.US);

В теории это может быть быстрее, но я не уверен, что это.

PS: Если вы укажете parseLenient() до части года, он также будет правильно разбирать 4-значные годы (т.е. "2015-JAN-12").