JDK8: невозможно разобрать LocalTime

Мне удалось проанализировать String объект LocalDate:

DateTimeFormatter f1=DateTimeFormatter.ofPattern("dd MM yyyy");
LocalDate d=LocalDate.parse("26 08 1984",f1);
System.out.println(d); //prints "1984-08-26"

Но я не могу сделать то же самое с LocalTime. Этот фрагмент кода:

DateTimeFormatter f2=DateTimeFormatter.ofPattern("hh mm");
LocalTime t=LocalTime.parse("11 08",f2); //exception here
System.out.println(t);

Выбрасывает a DateTimeParseException:

Exception in thread "main" java.time.format.DateTimeParseException: Text '11 08' could not be parsed: Unable to obtain LocalTime from TemporalAccessor: {MinuteOfHour=8, HourOfAmPm=11},ISO of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(Unknown Source)
    at java.time.format.DateTimeFormatter.parse(Unknown Source)
    at java.time.LocalTime.parse(Unknown Source)
    at com.mui.cert.Main.<init>(Main.java:21)
    at com.mui.cert.Main.main(Main.java:12)
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {MinuteOfHour=8, HourOfAmPm=11},ISO of type java.time.format.Parsed
    at java.time.LocalTime.from(Unknown Source)
    at java.time.LocalTime$$Lambda$15/1854731462.queryFrom(Unknown Source)
    at java.time.format.Parsed.query(Unknown Source)
    ... 4 more

Что я делаю неправильно?

Ответ 1

Если вы используете определенный формат, в соответствии с API:

Строка должна представлять допустимое время и анализируется с помощью DateTimeFormatter.ISO_LOCAL_TIME.

hh mm 

в течение 24h должно быть

HH mm

или за 12 часов

kk mm

Обработанные форматы должны иметь следующие условия:

  • Две цифры для часового дня. Это предварительно заполнено нулем, чтобы обеспечить две цифры.
  • Двоеточие
  • Две цифры для минуты-часа. Это предварительно заполнено нулем, чтобы обеспечить две цифры.
  • Если вторая минута недоступна, формат будет завершен.
  • Двоеточие
  • Две цифры для второй минуты. Это предварительно заполнено нулем, чтобы обеспечить две цифры.
  • Если nano-of-second равно нулю или недоступно, формат будет завершен.
  • Десятичная точка
  • От одной до девяти цифр для nano-of-second. Поскольку многие цифры будут выводиться по мере необходимости.

Ответ 2

Использовать DateTimeFormatter.ofPattern("kk mm"); для 12-часовых часов или DateTimeFormatter.ofPattern("HH mm") для 24-часового времени

Если вы хотите проанализировать время с помощью hh, вы должны объединить его с a, где вы определяете AM или PM:

DateTimeFormatter f2 = DateTimeFormatter.ofPattern("hh mm a");
LocalTime t = LocalTime.parse("11 08 AM", f2);

Ответ 3

В этом случае Unable to obtain LocalTime from TemporalAccessor означает, что он не может определить, как далеко в течение дня данная строка представляет, т.е. недостаточно информации для построения LocalTime. За кулисами код выглядит примерно так: расширенная версия Java 8 (которая дает аналогичную ошибку):

DateTimeFormatter f2 = DateTimeFormatter.ofPattern("hh mm");
TemporalAccessor temporalAccessor = f2.parse("11 08");
LocalTime t = temporalAccessor.query(LocalTime::from);
System.out.println(t);

В документации LocalTime::from указано

Преобразование использует запрос TemporalQueries.localTime(), который опирается на извлечение поля NANO_OF_DAY.

Ваша ошибка говорит вам, что TemporalAccessor имеет только два поля, ни одно из которых не является полем NANO_OF_DAY. Минимально допустимые шаблоны для извлечения a LocalTime с помощью DateTimeFormatter:

DateTimeFormatter.ofPattern("ha");
DateTimeFormatter.ofPattern("Ka");
DateTimeFormatter.ofPattern("ah");
DateTimeFormatter.ofPattern("aK");
DateTimeFormatter.ofPattern("k");
DateTimeFormatter.ofPattern("H");

Ваш шаблон должен содержать хотя бы одну из этих строк, чтобы получить поле NANO_OF_DAY во внутреннем TemporalAccessor, из которого может быть сконфигурирован LocalTime.

Ответ 4

Вам нужно использовать капитал HH в шаблоне

DateTimeFormatter f2=DateTimeFormatter.ofPattern("HH mm");

или сделайте это, для clock-hour-of-am-pm вам нужно указать его.

Это также должно работать

DateTimeFormatter f2=DateTimeFormatter.ofPattern("hh mm a");
LocalTime t=LocalTime.parse("11 08 AM",f2); //exception here