2015-05-18 1 views
3

Java DateTimeFormatter генерирует исключение для того, когда вы пытаетесь дату, которая выходит за пределы возможного диапазона, например:DateTimeFormatter автоматически корректирует дату недействителен (синтаксически возможно) календарь

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy"); 
String dateString = "12/32/2015"; 
LocalDate ld = LocalDate.parse(dateString, dtf); 

отбросит:

Exception in thread "main" java.time.format.DateTimeParseException: Text '12/32/2015' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 32 

Но когда я ввести неверную дату календаря, который по-прежнему синтаксически возможно по их меркам, это autocorrects, чтобы быть действительной датой, например:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy"); 
String dateString = "2/31/2015"; 
LocalDate ld = LocalDate.parse(dateString, dtf); 

он успешно разбирает, но автоподтверждает 2015-02-28. Я не хочу этого поведения, я хочу, чтобы он все еще выдавал исключение, когда дата не является действительной датой календаря. Есть ли встроенный параметр, который я могу установить для этого, или мне действительно нужно попытаться вручную отфильтровать эти экземпляры?

ответ

5

Вы можете использовать стиль в STRICT распознавателя:

import static java.time.format.ResolverStyle.STRICT; 

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/uuuu").withResolverStyle(STRICT); 

По умолчанию ofPattern использует a SMART resolver style, который будет использовать разумные значения по умолчанию.

Обратите внимание, что я использовал uuuu вместо yyyy, то есть YEAR вместо YEAR_OF_ERA. Предполагая, что вы находитесь в григорианской системе календаря, они эквивалентны годам в нынешнюю эпоху (год 1 или больше). Разница объясняется более подробно в ссылках выше.

+0

Это дает мне другое исключение: 'Text '2/28/2015' не может быть разобран: Невозможно получить LocalDate из TemporalAccessor: {DayOfMonth = 28, YearOfEra = 2015, MonthOfYear = 2}, типа ISO java.time.format.Parsed' – aconkey

+0

В сообщении говорится, что эпоха отсутствует - в строгом режиме она больше не по умолчанию. Вам нужно использовать 'DateTimeFormatterBuilder' и' parseDefaulting (ChronoField.ERA, IsoEra.CE.getValue()) 'http://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatterBuilder .html # parseDefaulting-java.time.temporal.TemporalField-long- – JodaStephen

+0

Не можем ли мы просто заменить 'yyyy'' uuuu' в этом случае? – assylias