Неможливо отримати 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.