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


150

Я просто намагаюся перетворити рядок дати в об’єкт 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

71

Якщо вам дійсно потрібно перетворити дату в об’єкт LocalDateTime, ви можете використовувати LocalDate.atStartOfDay (). Це дасть вам об’єкт LocalDateTime у вказану дату, для поля години, хвилини та другого значення встановлено 0:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();

2
Виправлення: встановіть час, який би був на початку цього дня .
— Трежказ

20
LocalDateTime.fromздається непотрібним, оскільки atStartOfDay()вже повертається LocalDateTime.
— Даріуш

1
scala: val time = LocalDate.parse ("20171220", DateTimeFormatter.ofPattern ("yyyyMMdd")). atStartOfDay.format (DateTimeFormatter.ofPattern ("yyyy-MM-dd HH: mm: ss"))
— Вуді ВС

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

(Спочатку це рішення було коментарем до відповіді ретрографії, але мене попросили опублікувати як окрему відповідь, тому що, мабуть, дуже добре працює для багатьох людей.)


1
Відповідь на те, чому "u" замість "y", відповіли у цьому посиланні uuuu-vers-yyyy-in-datetimeformatter-formatting-pattern- code -in-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 години за допомогою великої букви Н виправляє його:

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

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.