Автор оригинала: 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 .