2014-12-25 12 views
10

Próbowałem przez 4 godziny, aby to zrozumieć.Błąd przetwarzania składni Java LocalDateTime

: To działa

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

: To nie

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

Jedyna różnica polega na miesiąc wszystkie aktywowane. Właściwy przypadek Jul działa. Ani JUL, ani Jul nie będą działać. Próbowałem również wzór "LLL" bez powodzenia. Czego mi brakuje??

+0

Java jest wielkość liter – Evorlor

+0

Jamesa odpowiedź jest prawidłowa. Użyj DateTimeFormatterBuilder.parseCaseInsensitive() – JodaStephen

Odpowiedz

1

Wygląda na to, że nie jest obsługiwane przez official 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 

Jedynym rozwiązaniem dla miesiąca od roku jest tam, a nie jawnie wspomnieć dowolny format wspierającą trzyliterowy kapitał miesięcy.

To nie jest strasznie trudne do konwersji z powrotem do formatu, który Java może przestrzegać; wiąże się to trochę ze sfinalizowaniem daty i umieszczeniem jej w jednym ciągu.

Rozwiązanie poniżej nie jest tak eleganckie ani tak czyste jak korzystanie z usług osób trzecich, ale dodatkową korzyścią jest to, że w ogóle nie trzeba polegać na bibliotece strony trzeciej dla tego kodu.

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(); 
} 
+0

Dzięki. Wydaje mi się, że projektanci API wyznaczyliby taką powszechną odmianę form spraw. Dzięki za urywek. –

0

M z definicji przyjmuje July; Jul; 07. Może chcesz spróbować (rozwiązanie jest trochę brzydki):

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)); 

Albo można spróbować użyć WordUtils z apache-commons dla capitalize.

11

Najwyraźniej musiałem poświęcić 5 godzin na to. Podczas pisania rozszerzenia, aby zapewnić obejście, odkryłem to.

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()); 

Działa doskonale do wszystkich stylów obudowy.

+0

To powinno być oznaczone jako zaakceptowana odpowiedź. – navkast

1

Spróbuj użyć funkcji DateTimeFormatterBuilder i dostosuj wielkość liter w analizatorze. Nie zapomnij podać ustawień narodowych. Inaczej miesięcy skrót nie może być analizowany przez MMM w domyślnej lokalizacji:

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

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

'.parseCaseInsensitive()' jest tym, czego potrzebowałem. Dzięki. – Basil