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. LocalDate.parse() for 'yyyy-MM-dd'
Pattern
The best chances are that your application is already using Java 8 or 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 :
- four digits or more for the year where 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.
1.2. DateTimeFormatter for Custom Patterns
If we do have our own custom date pattern then we can create 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 a valid value and treated as the last day of the month. - Many times, this smart resolution is not aligned to business needs and we want to raise parse exceptions if such invalid values are encountered. Use
ResolverStyle.STRICT
to resolve dates and times strictly. Using strict resolution will ensure that all parsed values are within the outer range of valid values for the field.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(dateFormat)
.withResolverStyle(ResolverStyle.STRICT);
We can use LocalDate’s parse(dateString, dateTimeFormatter)
to parse the string to Localdate
instance.
LocalDate.parse(dateString dateFormatter);
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.
The given below is a Java program to check if a given date is in a valid format of “MM-dd-yyyy“.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
public class JavaDateValidations {
static DateTimeFormatter dateFormatter =
DateTimeFormatter.ofPattern("MM-dd-yyyy")
.withResolverStyle(ResolverStyle.STRICT);
public static void main(String[] args) {
LocalDate parsedLocalDate
= validateAndParseDateJava8("05-26-0020", dateFormatter);
System.out.println(parsedLocalDate);
}
public static LocalDate validateAndParseDateJava8(String dateStr,
DateTimeFormatter dateFormatter) {
LocalDate date = null;
try {
date = LocalDate.parse(dateStr, dateFormatter);
} catch (DateTimeParseException e) {
//handle exception
e.printStackTrace();
}
return date;
}
}
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.
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class JavaDateValidations { public static void main(String[] args) { String dateFormat = "MM-dd-yyyy"; String dateString = "05-26-2020"; Date parsedDate = validateAndParseDateJava7(dateString, dateFormat); System.out.println(parsedDate); } //Java 7 - Use SimpleDateFormat (not thread-safe) public static Date validateAndParseDateJava7(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; } }
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)
ordtf.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 chances of manual errors are high.
- If you have the liberty to upgrade a Java 7 application to latest Java version, please do on priority. The thread-safe and immutable nature of
DateTimeFormatter
is a huge win in terms of performance overSimpleDateFormat
.
Happy Learning !!
Leave a Reply