Автор оригинала: Chandra Prakash.
1. введение
В этом уроке мы обсудим различные способы проверки того, содержит ли Строка допустимую дату в Java.
Мы обсудим решения до Java 8, после Java 8 и с использованием валидатора Apache Commons .
2. Обзор Проверки данных
Всякий раз, когда мы получаем данные в любом приложении, нам необходимо убедиться, что они действительны, прежде чем выполнять дальнейшую обработку.
В случае ввода данных нам может потребоваться проверить следующее:
- Входные данные содержат дату в допустимом формате, например ММ/ДД/ГГГГ
- Различные части входных данных находятся в допустимом диапазоне
- Входные данные преобразуются в действительную дату в календаре
Для этого мы можем использовать регулярные выражения. Однако регулярные выражения для обработки различных форматов и языков ввода сложны и подвержены ошибкам. Кроме того, они могут ухудшить производительность.
Мы обсудим различные способы реализации проверки данных гибким, надежным и эффективным способом.
Во-первых, давайте напишем интерфейс для проверки данных:
public interface DateValidator { boolean isValid(String dateStr); }
В следующих разделах мы реализуем этот интерфейс, используя различные подходы.
3. Проверьте С помощью DateFormat
Java с самого начала предоставляла возможности для форматирования и анализа дат. Эта функциональность находится в DateFormat абстрактном классе и его реализации — SimpleDateFormat .
Давайте реализуем проверку данных с помощью метода parse класса DateFormat :
public class DateValidatorUsingDateFormat implements DateValidator { private String dateFormat; public DateValidatorUsingDateFormat(String dateFormat) { this.dateFormat = dateFormat; } @Override public boolean isValid(String dateStr) { DateFormat sdf = new SimpleDateFormat(this.dateFormat); sdf.setLenient(false); try { sdf.parse(dateStr); } catch (ParseException e) { return false; } return true; } }
Поскольку Формат Даты и связанные классы не являются потокобезопасными , мы создаем новый экземпляр для каждого вызова метода.
Далее давайте напишем модульный тест для этого класса:
DateValidator validator = new DateValidatorUsingDateFormat("MM/dd/yyyy"); assertTrue(validator.isValid("02/28/2019")); assertFalse(validator.isValid("02/30/2019"));
Это было наиболее распространенным решением до Java 8.
4. Проверьте С Помощью LocalDate
Java 8 представила улучшенный API даты и времени . Он добавил класс LocalDate , который представляет дату без времени. Этот класс является неизменяемым и потокобезопасным.
Локальная дата предоставляет два статических метода для анализа дат. Оба они используют DateTimeFormatter для фактического анализа:
public static LocalDate parse(CharSequence text) // parses dates using using DateTimeFormatter.ISO_LOCAL_DATE public static LocalDate parse(CharSequence text, DateTimeFormatter formatter) // parses dates using the provided formatter
Давайте используем метод parse для реализации проверки данных:
public class DateValidatorUsingLocalDate implements DateValidator { private DateTimeFormatter dateFormatter; public DateValidatorUsingLocalDate(DateTimeFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public boolean isValid(String dateStr) { try { LocalDate.parse(dateStr, this.dateFormatter); } catch (DateTimeParseException e) { return false; } return true; } }
Реализация использует объект DateTimeFormatter для форматирования. Поскольку этот класс потокобезопасен, мы используем один и тот же экземпляр для разных вызовов методов.
Давайте также добавим модульный тест для этой реализации:
DateTimeFormatter dateFormatter = DateTimeFormatter.BASIC_ISO_DATE; DateValidator validator = new DateValidatorUsingLocalDate(dateFormatter); assertTrue(validator.isValid("20190228")); assertFalse(validator.isValid("20190230"));
5. Проверка с помощью DateTimeFormatter
В предыдущем разделе мы видели, что LocalDate использует DateTimeFormatter объект для синтаксического анализа. Мы также можем использовать класс DateTimeFormatter непосредственно для форматирования и синтаксического анализа.
DateTimeFormatter анализирует текст в два этапа. На этапе 1 он анализирует текст в различные поля даты и времени в зависимости от конфигурации. На этапе 2 он преобразует проанализированные поля в объект даты и/или времени.
Атрибут ResolverStyle управляет этапом 2. Это перечисление , имеющее три возможных значения:
- СНИСХОДИТЕЛЬНО – разрешает даты и время снисходительно
- ИНТЕЛЛЕКТУАЛЬНОЕ – интеллектуальное разрешение дат и времени
- СТРОГО – строго определяет даты и время
Теперь давайте запишем проверку данных с помощью DateTimeFormatter напрямую:
public class DateValidatorUsingDateTimeFormatter implements DateValidator { private DateTimeFormatter dateFormatter; public DateValidatorUsingDateTimeFormatter(DateTimeFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public boolean isValid(String dateStr) { try { this.dateFormatter.parse(dateStr); } catch (DateTimeParseException e) { return false; } return true; } }
Далее давайте добавим модульный тест для этого класса:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.US) .withResolverStyle(ResolverStyle.STRICT); DateValidator validator = new DateValidatorUsingDateTimeFormatter(dateFormatter); assertTrue(validator.isValid("2019-02-28")); assertFalse(validator.isValid("2019-02-30"));
В приведенном выше тесте мы создаем DateTimeFormatter на основе шаблона и локали. Мы используем строгое разрешение для дат.
6. Проверка С Помощью Валидатора Apache Commons
Проект Apache Commons предоставляет платформу проверки. Это содержит процедуры проверки, такие как дата, время, номера, валюта, IP-адрес, адрес электронной почты и URL.
Для нашей цели в этой статье давайте рассмотрим класс GenericValidator , который предоставляет несколько методов для проверки того, содержит ли строка допустимую дату:
public static boolean isDate(String value, Locale locale) public static boolean isDate(String value,String datePattern, boolean strict)
Чтобы использовать библиотеку, давайте добавим в наш проект зависимость commons-validator Maven:
commons-validator commons-validator 1.6
Далее, давайте использовать класс GenericValidator для проверки дат:
assertTrue(GenericValidator.isDate("2019-02-28", "yyyy-MM-dd", true)); assertFalse(GenericValidator.isDate("2019-02-29", "yyyy-MM-dd", true));
7. Заключение
В этой статье мы рассмотрели различные способы проверки того, содержит ли строка допустимую дату.
Как обычно, полный исходный код можно найти на GitHub .