Ошибка локального анализа Java LocalDateTime

Пробовал в течение 4 часов, чтобы понять это.

: Это работает

String date = "Jul-01-2014 09:10:12";
LocalDateTime dt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("MMM-dd-yyyy HH:mm:ss", Locale.US));

: Это не будет

String date = "Jul-01-2014 09:10:12";
LocalDateTime dt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("MMM-dd-yyyy HH:mm:ss", Locale.US));

Единственное различие заключается в том, что весь месяц заглавны. Правильный случай работы Юля. Ни JUL, ни jul не будут работать. Я также попробовал шаблон "LLL" без везения. Что мне не хватает?

Ответ 1

Не похоже, что это поддерживается официальным API .

Symbol  Meaning                     Presentation      Examples
  ------  -------                     ------------      -------
   G       era                         text              AD; Anno Domini; A
   u       year                        year              2004; 04
   y       year-of-era                 year              2004; 04
   D       day-of-year                 number            189
   M/L     month-of-year               number/text       7; 07; Jul; July; J
   d       day-of-month                number            10

Единственный вариант для месяца в году, и он явно не упоминает какой-либо формат, поддерживающий три месяца большой буквы.

Не сложно перевести его обратно в формат, который Java может уважать; это связано с небольшим сокращением даты и возвратом его в одну строку.

Нижеприведенное решение не так изящно или чище, как с использованием стороннего производителя, но дополнительное преимущество заключается в том, что не нужно вообще полагаться на стороннюю библиотеку для этого кода.

public String transformToNormalizedDateFormat(final String input) {
    String[] components = input.split("-");
    String month = components[0];
    if(month.length() > 3) {
        throw new IllegalArgumentException("Was not a date in \"MMM\" format: " + month);
    }
    // Only capitalize the first letter.
    final StringBuilder builder = new StringBuilder();
    builder.append(month.substring(0, 1).toUpperCase())
            .append(month.substring(1).toLowerCase())
            .append("-");
    final StringJoiner stringJoiner = new StringJoiner("-");
    Arrays.stream(components, 1, components.length).forEach(stringJoiner::add);
    builder.append(stringJoiner.toString());
    return builder.toString();
}

Ответ 2

Ну, видимо, мне нужно было потратить 5 часов на это. При написании расширения для обеспечения обходного пути я обнаружил это.

    String date = "01-JUL-2014 09:10:12";

    DateTimeFormatterBuilder fmb = new DateTimeFormatterBuilder();
    fmb.parseCaseInsensitive();
    fmb.append(DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss"));

    LocalDateTime dt = LocalDateTime.parse(date, fmb.toFormatter());

Отлично подходит для всех стилей case.

Ответ 3

Попробуйте использовать DateTimeFormatterBuilder и сделать парсер без учета регистра. Не забудьте указать локаль. В противном случае аббревиатура месяца может не обрабатываться MMM в локали по умолчанию:

DateTimeFormatter format = new DateTimeFormatterBuilder()
  .parseCaseInsensitive()
  .appendPattern("dd-MMM-yyyy")
  .toFormatter(Locale.ENGLISH);

LocalDate.parse("03-jun-2015", format);

Ответ 4

M по определению принимает July; Jul; 07. Вы можете попробовать (решение будет немного уродливым):

date = Character.toUpperCase(date.charAt(0)) + date.substring(1).toLowerCase();
LocalDateTime dt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("MMM-dd-yyyy HH:mm:ss", Locale.US));

Или вы можете попробовать WordUtils от apache-commons для capitalize.