Есть ли хороший синтаксический анализатор даты * для Java?

Есть ли хороший, строгий синтаксический анализатор даты для Java? У меня есть доступ к Joda-Time, но я еще не видел этот вариант. Я нашел вопрос "Есть ли хороший синтаксический анализатор для Java", и, хотя это связано, это похоже на противоположное. Принимая во внимание, что этот вопрос требует мягкой, более нечеткой логики и подвержен человеческому парсеру ошибок, я бы хотел строгого парсера. Например, как JodaTime (насколько я могу судить), так и simpleDateFormat, если у вас есть формат "MM/dd/yyyy":

проанализируйте это: 40/40/4353

Это станет действительной датой. Я хочу, чтобы парсер знал, что 40 - неверный месяц и дата. Конечно, какая-то реализация этого существует в Java?

Ответ 1

Я не вижу, что Joda признает это как действительную дату. Пример:

strict = org.joda.time.format.DateTimeFormat.forPattern("MM/dd/yyyy")
try {
    strict.parseDateTime('40/40/4353')
    assert false
} catch (org.joda.time.IllegalFieldValueException e) {
    assert 'Cannot parse "40/40/4353": Value 40 for monthOfYear must be in the range [1,12]' == e.message
}




Насколько я могу судить, ни DateFormat с setLenient (false ). Пример:

try {
    df = new java.text.SimpleDateFormat('MM/dd/yyyy')
    df.setLenient(false)
    df.parse('40/40/4353')
    assert false
} catch (java.text.ParseException e) {
    assert e.message =~ 'Unparseable'
}

Надеюсь, это поможет!

Ответ 2

Хороший способ выполнить строгую проверку с помощью DateFormat - это переформатирование разобранной даты и проверка равенства исходной строки:

String myDateString = "87/88/9999";
Date myDate = dateFormat.parse(myDateString);
if (!myDateString.equals(df.format(myDate))){
  throw new ParseException();
}

Работает как шарм.

Ответ 3

Вы можете использовать apache.commons.validator.routines.DateValidator для проверки даты, если вы не хотите использовать SimpleDateFormat.

Пример:

 public static Date validateDate(String value, String pattern) {
       DateValidator validator = new DateValidator();
       Date date = null;
           if (pattern!=null) {    //Pattern is passed
               date = validator.validate(value, pattern);
           } else {
               date = validator.validate(value);
           }
       return date;
    }

Таким образом, если возвращается значение NULL, это означает, что дата недействительна, в противном случае она является действительной датой. Этот метод является альтернативой использованию SimpleDateFormat как вам не нужно полагаться на исключение, которое выдается, чтобы определить, является ли это действительной датой или нет,