Невозможно получить LocalDateTime из TemporalAccessor при разборе LocalDateTime (Java 8)

151

Я просто пытаюсь преобразовать строку даты в объект DateTime в Java 8. После запуска следующих строк:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime dt = LocalDateTime.parse("20140218", formatter);

Я получаю следующую ошибку:

Exception in thread "main" java.time.format.DateTimeParseException: 
Text '20140218' could not be parsed: 
Unable to obtain LocalDateTime from TemporalAccessor: 
{},ISO resolved to 2014-02-18 of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)

Синтаксис идентичен тому, что было предложено здесь , но мне подают исключение. Я использую JDK-8u25.

зеркальное письмо
источник

Ответы:

177

Оказывается, Java не принимает пустое значение Date в качестве DateTime. Использование LocalDate вместо LocalDateTime решает проблему:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);
зеркальное письмо
источник
42
Для чего это стоит: у меня была такая же проблема даже при использовании LocalDateи нет LocalDateTime. Проблема заключалась в том, что я создал свое DateTimeFormatterиспользование .withResolverStyle(ResolverStyle.STRICT);, поэтому мне пришлось использовать шаблон даты uuuuMMddвместо yyyyMMdd(то есть «год» вместо «год эры»)!
ZeroOne
72

Если вам действительно нужно преобразовать дату в объект LocalDateTime, вы можете использовать LocalDate.atStartOfDay (). Это даст вам объект LocalDateTime на указанную дату с полями часа, минуты и секунды, равными 0:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();
Ойвинд Мо
источник
2
Исправление: установите любое время, которое будет в начале этого дня .
Trejkaz
20
LocalDateTime.fromкажется ненужным, так как atStartOfDay()уже возвращается LocalDateTime.
Дариуш
1
Скала: Val время = LocalDate.parse ( "20171220", DateTimeFormatter.ofPattern ( "ГГГГММДД")) atStartOfDay.format (DateTimeFormatter.ofPattern ( "гггг-ММ-дд чч: мм: сс")).
Древесный вс
48

Для чего стоит, если кто-то должен прочитать эту тему еще раз (как и я), правильный ответ будет в DateTimeFormatterопределении, например:

private static DateTimeFormatter DATE_FORMAT =  
            new DateTimeFormatterBuilder().appendPattern("dd/MM/yyyy[ [HH][:mm][:ss][.SSS]]")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .toFormatter(); 

Нужно установить дополнительные поля, если они появятся. И остальной код должен быть точно таким же.

Юлиан Давид
источник
1
Это действительно универсальное решение, например, для такого метода: Long getFileTimestamp (String file, Pattern pattern, DateTimeFormatter dtf, int group); Здесь у вас есть разные шаблоны и DateTimeFormetter, без указания времени.
toootooo
Это может быть статическое поле? Я не нашел в Javadoc, что экземпляр, созданный таким образом, является потокобезопасным
Kamil Roman
Не забудьте добавить parseDefaultingПОСЛЕ того, как вы позвонили appendPattern. Иначе это дастDateTimeParseException .
wittyameta
31

Это действительно неясное и бесполезное сообщение об ошибке. После долгих проб и ошибок я обнаружил, что LocalDateTimeэто даст вышеуказанную ошибку, если вы не попытаетесь проанализировать время. Используя LocalDateвместо этого, он работает без ошибок.

Это плохо документировано, и соответствующее исключение очень бесполезно.

Том Б
источник
25

Расширяя ответ ретрографии ..: У меня была такая же проблема даже при использовании LocalDateи нет LocalDateTime. Проблема заключалась в том, что я создал свое DateTimeFormatterиспользование .withResolverStyle(ResolverStyle.STRICT);, поэтому мне пришлось использовать шаблон даты uuuuMMddвместо yyyyMMdd(то есть «год» вместо «год эры»)!

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
  .parseStrict()
  .appendPattern("uuuuMMdd")
  .toFormatter()
  .withResolverStyle(ResolverStyle.STRICT);
LocalDate dt = LocalDate.parse("20140218", formatter);

(Это решение изначально было комментарием к ответу ретрографии, но мне было рекомендовано опубликовать его как отдельный ответ, потому что оно, по-видимому, действительно хорошо работает для многих людей.)

ZeroOne
источник
1
Ответ, почему «и» вместо «у» был дан ответ в этой связи уууу-против-YYYY-в-DateTimeFormatter-форматирования профилированное-коды-в-Java @Peru
Prashanth
23

Для тех, кто попал сюда с этой ошибкой, как я сделал:

Unable to obtain LocalDateTime from TemporalAccessor: {HourOfAmPm=0, MinuteOfHour=0}

Это произошло из следующей строки:

LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy h:mm"));

Оказалось, что это потому, что я использовал 12-часовую схему на 0 часов вместо 24-часовой.

Изменение часового на 24-часовой шаблон с использованием заглавной буквы H исправляет это:

LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy H:mm"));
mawburn
источник
12

Если строка даты не содержит значения для часов, минут и т. Д., Вы не можете напрямую преобразовать это значение в a LocalDateTime. Вы можете только преобразовать его к LocalDate, потому что строка только представляют в год, месяц и день компонентов было бы правильным , что нужно сделать.

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf); // 2018-03-06

В любом случае вы можете преобразовать это в LocalDateTime.

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf);
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00
простое число
источник
Также убедитесь, что формат правильный. Это исправление не работало для меня до тех пор, пока я не установил формат, yyyy-mm-ddкогда он должен был быть yyyy-MM-dd.
patstuart
0

Попробуй это:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy"); 
LocalDate fromLocalDate = LocalDate.parse(fromdstrong textate, dateTimeFormatter);

Вы можете добавить любой формат, который вы хотите. Это подходит для меня!

Виная Касарла
источник
0

Это отлично работает

public class DateDemo {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm");
        String date = "16-08-2018 12:10";
        LocalDate localDate = LocalDate.parse(date, formatter);
        System.out.println("VALUE="+localDate);

        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
        LocalDateTime parse = LocalDateTime.parse(date, formatter1);
        System.out.println("VALUE1="+parse);
    }
}

вывод:

VALUE=2018-08-16
VALUE1=2018-08-16T12:10
Джефф Кук
источник