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 beyond.
1. DateTimeFormatter – Java 8
- 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 using
LocalDate
class. - By default,
LocalDate.parse()
method parsed a date usingISO_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.
- If we do have our own custom date pattern then we can create using
DateTimeFormatter.ofPattern()
method. By deafult, theResolverStyle.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 value and treated as last day of the month. - Many times, this smart resolution is not aligned to business needs and we want to raise parsing 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. - Use LocalDate’s
parse(dateString, dateTimeFormatter)
to parse the string toLocaldate
instance. DateTimeFormatter
instance is thread safe and immutable so we can create only one instance per pattern/application and share it across the other functions.
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; public class JavaDateValidations { public static void main(String[] args) { String dateFormat = "MM-dd-yyyy"; String dateString = "05-26-2020"; DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(dateFormat) .withResolverStyle(ResolverStyle.STRICT); LocalDate parsedLocalDate = validateAndParseDateJava8(dateString, dateFormatter); System.out.println(parsedLocalDate); } //Java 8 - Use DateTimeFormatter (thread-safe) public static LocalDate validateAndParseDateJava8(String dateStr, DateTimeFormatter dateFormatter) { LocalDate date = null; try { date = LocalDate.parse(dateStr, dateFormatter); } catch (DateTimeParseException e) { e.printStackTrace(); } return date; } }
2. SimpleDateFormat – Java 7
- In case you are still struck 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 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 exceptionParseException
which signals that some error has been occured while parsing the date string tojava.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 Date Validation
Below are some best practices which 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 Java 8, please do on priority. The thread-safe and immutable nature of
DateTimeFormatter
is a huge win in terms of performance overSimpleDateFormat
.
Drop me your questions and suggestions related to parsing string to date objects in Java
in comments.
Happy Learning !!
Was this post helpful?
Let us know if you liked the post. That’s the only way we can improve.
Dave
Given a random string, how would I determine if the string is really a valid date? I can’t know the format in advance.
For example, my app received the following from different sources and has no knowledge of the format;
1. 02-JUL-2020 – IsDateValid should return true
2. July 02, 2020 – IsDateValid should return true
3. July 45, 2020 – IsDateValid should return false