Ответ 1
fmt.setLenient(false);
- это то, что вы ищете.
SimpleDateFormat - очень добрый парсер, который откатывает результирующую дату вместо того, чтобы бросать ошибку. Как я могу анализировать дату строго без регулярных выражений и т.д.?
fmt = new SimpleDateFormat("dd.MM.yyyy")
fmt.parse("10.11.2012") // it works
fmt.parse("10.1150.2012") // it works but it unwanted
fmt.setLenient(false);
- это то, что вы ищете.
Вы также можете использовать пакет 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
К сожалению, 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() есть функциональные инверсии. Это то, что я ожидаю от большинства людей.