2015-07-24 1 views
18

Мой ввод представляет собой строковое представление даты в формате «01-07-2015» на 1 июля 2015 года. Я пытаюсь разобрать это в переменную java.time.LocalDate :Не удается разобрать String на LocalDate (Java 8)

final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd-MM-YYYY"); 
final String input = "01-07-2015"; 
final LocalDate localDate = LocalDate.parse(input, DATE_FORMAT); 

Основано на DateTimeFormatter JavaDoc, я ожидаю, что это сработает. Тем не менее, я поздоровался с очень внимательным и обходительным сообщением:

причиненном: java.time.DateTimeException: Невозможно получить LocalDate из TemporalAccessor: {DayOfMonth = 1, MonthOfYear = 7, WeekBasedYear [WeekFields [ПОНЕДЕЛЬНИК , 4]] = 2015}, ISO типа java.time.format.Parsed

Я не совсем понимаю, что это исключение говорит мне. Может ли кто-нибудь объяснить мне, что происходит не так?

+9

Вы должны выбрать 'yyyy' вместо' YYYY' – adatapost

ответ

25

В год вы должны использовать строчную у:

final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd-MM-yyyy"); 

Прописная Y используется для weekyear. См. javadoc of DateTimeFormatter для более подробной информации.

+3

Просто из любопытства, как сообщение об ошибке связано с тем, что 'Y' для _weekyear_, а' y' - для _year_? – mthmulders

+4

Сообщение об ошибке говорит {DayOfMonth = 1, MonthOfYear = 7, WeekBasedYear [WeekFields [MONDAY, 4]] = 2015}, это означает, что он разобрал 1 из вашей входной строки как DayOfMonth (потому что вы использовали «d» в своем шаблоне), 7 был проанализирован как MonthOfYear (из-за «M» в вашем шаблоне), а в 2015 году понималось значение WeekBasedYear (ака недели) из-за «Y» в вашем шаблоне – Kejml

+0

@mthmulders Иногда [сообщения об ошибках сосут] (http: //programmers.stackexchange .com/вопросы/278949/почему-делать-много-исключения-сообщений, не-содержит-полезную-деталь). Конечно, это исключение на самом деле не так уж плохо, и это говорит вам, что он пытался разобрать «ГГГГ». Я посмотрел [java datetimeformatter weekbasedyear] (https://www.google.com/search?q=java+datetimeformatter+weekbasedyear), и первый результат привел меня [здесь] (https://docs.oracle.com/javase /8/docs/api/java/time/format/DateTimeFormatter.html), в котором перечислены типы идентификаторов и что они означают. –

12

Ответ на вопрос - использовать 'y' not 'Y'.

Чтобы объяснить сообщение об ошибке, позволяет разложить его:

Unable to obtain LocalDate from TemporalAccessor

Это говорит, что он не может создать LocalDate (что было предложено) от TemporalAccessor (интерфейс низкого уровня, который обеспечивает hashmap- например, доступ к полям даты/времени).

of type java.time.format.Parsed

Это говорит о том, что объект, передаваемый в метод был типа java.time.format.Parsed. Это стандартный тип вывода синтаксического анализа и содержит всю информацию, которая была проанализирована.

{DayOfMonth=1, MonthOfYear=7, WeekBasedYear[WeekFields[MONDAY,4]]=2015},ISO

Это toString() форма java.time.format.Parsed объекта, что в результате синтаксического анализа. Он говорит, что четыре вещи были разобраны:

  • DayOfMonth=1, то день-месяц разобранной со значением 1
  • MonthOfYear=7, месяц-оф-год разобранной со значением 7
  • WeekBasedYear[WeekFields[MONDAY,4]]=2015, то неделю на основе года анализируется со значением 2015
  • ISO, что календарная система ISO (значение по умолчанию)

Поскольку невозможно создать LocalDate из комбинации DayOfMonth + MonthOfYear + WeekBasedYear, генерируется исключение.

Обратите внимание, что часть [WeekFields[MONDAY,4]] ссылается на то, что существует множество различных способов определения недели, в начале недели США в воскресенье, но в стандарте ISO и в ЕС они начинаются в понедельник.