Ошибка локального анализа 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
.