Научитесь проверять, содержит ли данная строка значение даты или нет. Мы изучим различные методы проверки даты, доступные в Java 7, Java 8 и выше.
1. LocalDate и DateTimeFormatter(Java 8 и более поздние версии)
1.1. Шаблон по умолчанию ->'yyyy-MM-dd'
Вероятнее всего, ваше приложение уже использует Java 8 или более позднюю версию. В этом случае лучшим способом представления даты в Java является использование класса LocalDate.
По умолчанию метод LocalDate.parse() анализирует дату с использованием шаблона ISO_LOCAL_DATE(yyyy-MM-dd). Формат состоит из следующего:
- четыре или более цифр для года, где диапазон от 0000 до 9999 будет предварительно дополнен нулями, чтобы обеспечить четыре цифры. Годы за пределами этого диапазона будут иметь префиксный положительный или отрицательный символ.
- две цифры для обозначения месяца года, предварительно дополненные нулями, чтобы гарантировать наличие двух цифр.
- две цифры для дня месяца, предварительно дополненные нулями, чтобы гарантировать наличие двух цифр.
LocalDate localDate = LocalDate.parse("2023-02-08"); //08-Feb-2023Assertions.assertNotNull(localDate);Assertions.assertEquals(8, localDate.getDayOfMonth());Assertions.assertEquals(2, localDate.getMonthValue());Assertions.assertEquals(2023, localDate.getYear());
1.2 Пользовательские шаблоны с DateTimeFormatter
Если у нас есть собственный шаблон даты, то мы можем создать его с помощью метода DateTimeFormatter.ofPattern().
- По умолчанию используется ResolverStyle.SMART, который использует разумное значение по умолчанию для каждого поля даты. Например, значение больше 31 для поля дня будет допустимым и будет рассматриваться как последний день месяца.
- Часто это интеллектуальное разрешение не соответствует потребностям бизнеса, и мы хотим вызывать исключения разбора, если встречаются такие недопустимые значения. Используйте ResolverStyle.STRICT для строгого разрешения дат и времени. Строгое разрешение гарантирует, что все проанализированные значения находятся в пределах внешнего диапазона допустимых значений поля.
static final String CUSTOM_PATTERN = "MM-dd-yyyy";static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(CUSTOM_PATTERN);
Помните, что экземпляр DateTimeFormatter является потокобезопасным и неизменяемым, поэтому мы можем создать только один экземпляр для каждого шаблона/приложения и использовать его совместно с другими функциями.
Мы можем использовать parse(dateString, dateTimeFormatter) LocalDate для преобразования строки в экземпляр Localdate.
public static LocalDate isValidLocalDate(String dateStr, DateTimeFormatter dateFormatter) {LocalDate date = null;try {date = LocalDate.parse(dateStr, dateFormatter);} catch(DateTimeParseException e) {//handle exceptione.printStackTrace();}return date;}
Ниже приведена программа Java для проверки того, соответствует ли заданная дата допустимому формату «MM-dd-yyyy».
LocalDate parsedLocalDate = isValidLocalDate("01-26-2023", DATE_TIME_FORMATTER);Assertions.assertNotNull(parsedLocalDate);Assertions.assertEquals(26, parsedLocalDate.getDayOfMonth());Assertions.assertEquals(1, parsedLocalDate.getMonthValue());Assertions.assertEquals(2023, parsedLocalDate.getYear());
2. SimpleDateFormat(Java 7)
Если вы все еще используете Java 7 и не можете выполнить обновление из-за зависимостей некоторых устаревших приложений, вы можете использовать SimpleDateFormat для проверки даты.
- Хотя SimpleDateFormat не является потокобезопасным или неизменяемым, он все же хорошо служит своей цели. Не используйте этот класс в многопоточной среде с дополнительной синхронизацией.
- Не забудьте использовать метод setLenient() для указания фактора снисходительности. При снисходительном разборе анализатор может использовать эвристику для интерпретации входных данных, которые не совсем соответствуют формату этого объекта. При строгом разборе входные данные должны соответствовать формату этого объекта.
Затем используйте метод parse(dateString) SimpleDateFormat, который выдает проверяемое исключение ParseException, сигнализирующее о том, что при анализе строки даты в объекте java.util.Date произошла ошибка.
public static Date isValidDate(String dateString, String dateFormat) {Date date = null;DateFormat sdf = new SimpleDateFormat(dateFormat);sdf.setLenient(false);try {date = sdf.parse(dateString);} catch(ParseException e) {e.printStackTrace();}return date;}
Мы можем использовать этот метод следующим образом:
String dateFormat = "MM-dd-yyyy";String dateString = "05-26-2020";Date parsedDate = isValidDate(dateString, dateFormat);
3. Лучшие практики проверки дат в Java
Ниже приведены некоторые рекомендации, которым вы можете следовать при проверке дат в Java.
- Хотя в 99% случаев это не будет иметь никакого значения, все равно рассмотрите возможность использования 'uuuu' вместо 'yyyy'. Обратитесь к этой теме SO для получения дополнительной информации.
- Используйте строгий синтаксический анализ с использованием соответствующих методов, например sdf.setLenient(false) или dtf.withResolverStyle(ResolverStyle.STRICT).
- Хотя строгий анализ дат решает большинство проблем, все равно рассмотрите возможность использования дополнительных проверок — например, допустимая проанализированная дата должна находиться в пределах предопределенного диапазона дат. Это может оказаться действительно полезным при массовом анализе записей, чувствительных к дате. Например, мы можем использовать этот тип проверки при импорте финансовых записей из большой таблицы Excel, где высока вероятность ручных ошибок.
- Если вы можете обновить приложение Java 7 до последней версии Java, пожалуйста, сделайте это в приоритетном порядке. Потокобезопасная и неизменяемая природа DateTimeFormatter — это огромный выигрыш с точки зрения производительности по сравнению с SimpleDateFormat.