Check if a Date is Valid in Java

Learn to validate if a given string contains a date value or not. We will learn various date validation techniques available in Java 7, Java 8 and above.

1. LocalDate and DateTimeFormatter (Java 8 and Later)

1.1. Default Pattern ->'yyyy-MM-dd'

The best chances are that your application already uses Java 8 or a later release. In this case, the best way to represent a date in Java is by using LocalDate class.

By default, LocalDate.parse() method parsed a date using ISO_LOCAL_DATE pattern (yyyy-MM-dd). The format consists of the following:

  • four digits or more for the year, where the range 0000 to 9999 will be pre-padded by zero to ensure four digits. Years outside that range will have a prefixed positive or negative symbol.
  • two digits for the month of the year and pre-padded by zero to ensure two digits.
  • two digits for the day of the month and pre-padded by zero to ensure two digits.
LocalDate localDate = LocalDate.parse("2023-02-08"); //08-Feb-2023

Assertions.assertNotNull(localDate);
Assertions.assertEquals(8, localDate.getDayOfMonth());
Assertions.assertEquals(2, localDate.getMonthValue());
Assertions.assertEquals(2023, localDate.getYear());

1.2. Custom Patterns with DateTimeFormatter

If we do have our own custom date pattern then we can create one using DateTimeFormatter.ofPattern() method.

  • By default, the ResolverStyle.SMART is used, which uses the sensible default for each date field. For example, a value greater than 31 for a day field will be valid and treated as the last day of the month.
  • Often, this smart resolution is not aligned with business needs, and we want to raise parse exceptions if such invalid values are encountered. Use ResolverStyle.STRICT to resolve dates and times strictly. The strict resolution will ensure that all parsed values are within the field’s outer range of valid values.
static final String CUSTOM_PATTERN = "MM-dd-yyyy";
static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(CUSTOM_PATTERN);

Remember that DateTimeFormatter instance is thread-safe and immutable, so we can create only one instance per pattern/application and share it across the other functions.

We can use LocalDate’s parse(dateString, dateTimeFormatter) to parse the string to Localdate instance.

public static LocalDate isValidLocalDate(String dateStr, DateTimeFormatter dateFormatter) {

  LocalDate date = null;
  try {
    date = LocalDate.parse(dateStr, dateFormatter);
  } catch (DateTimeParseException e) {
    //handle exception
    e.printStackTrace();
  }
  return date;
}

The given below is a Java program to check if a given date is in a valid format of “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)

In case you are still stuck at Java 7 and can’t upgrade due to some legacy application’s dependencies, you can use SimpleDateFormat for date validation.

  • Though SimpleDateFormat is not thread-safe or immutable, still, it serves the purpose pretty well. Do not use this class in a multi-threaded environment with added synchronization.
  • Do not forget to use setLenient() method to specify the leniency factor. With lenient parsing, the parser may use heuristics to interpret inputs that do not precisely match this object’s format. With strict parsing, inputs must match this object’s format.

Then use SimpleDateFormat‘s parse(dateString) method which throws checked exception ParseException which signals that some error has occurred while parsing the date string to java.util.Date object.

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;
}

We can use this method as follows:

String dateFormat = "MM-dd-yyyy";
String dateString = "05-26-2020";

Date parsedDate = isValidDate(dateString, dateFormat);

3. Best Practices for Java Date Validation

Below are some best practices you can follow during validating dates in Java.

  • Although, it will not make any difference in 99% cases, still consider using 'uuuu' instead of 'yyyy'. Refer to this SO thread for more information.
  • Use strict parsing using relevant methods i.e. sdf.setLenient(false) or dtf.withResolverStyle(ResolverStyle.STRICT).
  • Though strict date parsing solves most problems, still consider using extra checks – for example, a valid parsed date must lie within a predefined date range. This can prove really useful when parsing date-sensitive records in bulk. For example, we can use this kind of validation while importing financial records from a large excel sheet where the chances of manual errors are high.
  • If you can upgrade a Java 7 application to the latest Java version, please do on priority. The thread-safe and immutable nature of DateTimeFormatter is a huge win in terms of performance over SimpleDateFormat.

Happy Learning !!

Sourcecode Download

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode