Java: как строго разбирать дату?

SimpleDateFormat - очень добрый парсер, который откатывает результирующую дату вместо того, чтобы бросать ошибку. Как я могу анализировать дату строго без регулярных выражений и т.д.?

fmt = new SimpleDateFormat("dd.MM.yyyy")
fmt.parse("10.11.2012")   // it works
fmt.parse("10.1150.2012") // it works but it unwanted

Ответы

Ответ 2

java.time

Вы также можете использовать пакет java.time в Java 8 и более поздних версиях (Tutorial), Его синтаксический анализ строго проверяет значения даты.

Например:

String strDate = "20091504";
TemporalAccessor ta = DateTimeFormatter.ofPattern("yyyyMMdd").parse(strDate);

Прямо:

 
Exception in thread "main" java.time.format.DateTimeParseException:
Text '20091504' could not be parsed:
Invalid value for MonthOfYear (valid values 1 - 12): 15

Ответ 3

К сожалению, fmt.setLenient(false); не приведет к строгому форматированию даты. Это помогает некоторым, например, синтаксический анализ "2010-09-01" с использованием формата "yyyyMMdd" будет успешным, если lenient == true, но результат очень странный: 2009/12/09.

Даже если lenient == false parse() все еще действует мягко. "2010/01/5" разрешен для шаблона "yyyy/MM/dd". И разногласие данных, вроде "1999/2011" по шаблону "yyyy/yyyy", допускается (уступка 2011 года). Мусор также допускается после сопоставления с образцом. Например: "20100901" и "20100901andGarbage" будут соответствовать "yyyyMMdd".

Я написал расширение SimpleDateFormat, которое обеспечивает строгое сопоставление шаблонов. Вы можете найти его здесь:

SimpleDateFormat.parse() игнорирует количество символов в шаблоне

В моей версии format() и parse() есть функциональные инверсии. Это то, что я ожидаю от большинства людей.