Java DateFormat: самый удобный и элегантный способ проверки даты ввода по нескольким шаблонам

#java

#java

Вопрос:

Я делаю это сейчас:

 ......

DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
try{
    dateFormat.parse(criteria.getPeriodFrom());
    dateFormat.parse(criteria.getPeriodTo());
}
catch{
    errors.reject("Incorrect format");
}

......
  

Но что, если мне нужно проверить несколько приемлемых шаблонов (например, «дд.ММ.гггг», «ddMMyyyy» ….). И я не хочу выполнять какие-либо копирования и вставки или перебирать коллекцию DateFormats 🙂 Есть ли для этого классные библиотеки?

Комментарии:

1. Я не знаю, поможет ли это, но ознакомьтесь с JodaTime по адресу joda-time.sourceforge.net

Ответ №1:

Просто поместите цикл за пределы блока try / catch:

 boolean success = false;
for (DateFormat candidate : formats) {
    try {
        candidate.parse(criteria.getPeriodFrom());
        candidate.parse(criteria.getPeriodTo());
        success = true;
        break;
    }
    catch (ParseException e) {
        // Expected... move on
    }
}
if (!success) {
    errors.reject("Incorrect format");
}
  

К сожалению, ни встроенные библиотеки Java, ни обычно отличное время Joda не имеют ничего подобного.NET DateTime.TryParseExact , который позволяет вам проверить, работает ли операция синтаксического анализа, без уродливого исключения: (Имейте в виду, по крайней мере, форматеры Joda Time являются потокобезопасными и неизменяемыми.

РЕДАКТИРОВАТЬ: я могу ошибаться… по-видимому DateFormat.parse(String, ParsePosition) , просто возвращает null при сбое, поэтому вы могли бы использовать:

 for (DateFormat candidate : formats) {
    if (isValid(candidate, criteria)) {
        // whatever
    }
}

...
private static boolean isValid(DateFormat format, Criteria criteria) {
    return format.parse(criteria.getPeriodFrom(), new ParsePosition(0)) != null amp;amp;
           format.parse(criteria.getPeriodTo(), new ParsePosition(0)) != null))
}
  

Комментарии:

1. Это единственный способ, которым я видел, как это делается с использованием простой библиотеки Java. К вашему сведению, ваш оператор for, вероятно, должен быть for(DateFormat dateFormat : formats){...}

2. @JavaDrinker: Смотрите мою правку — я думаю, есть более приятный способ … смотрите мою правку.

3. @JonSkeet, который вы использовали DateFormat candidate , затем вызвал вашу функцию с dateFormat

4. @Mike: Упс, спасибо — я исправил это в первом фрагменте кода, но не во втором…