Monday 26 December 2016

Unknown facts about Date Format Validation in Java

Have you ever think of validating a date given in string form whether it's a valid date or not?
e.g. :
30-11-2016(dd-MM-yyyy)  --> Valid date
31-11-2016(dd-MM-yyyy)  --> Invalid date, since November has only 30 days

Now you think what is there, it's pretty simple. Now you can think of using any 3rd party utility library (like apache-common-util) to validate this.

But the point here is, how these utility libraries do this validation ? Now the java.text.SimpleDateFormat class in java core API comes to our mind.

Let's see an example how can we validate using this class :
Example - 1

SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
Date date = format.parse("31-JAN-2016");
System.out.println(date);

/*O/P---Sun Jan 31 00:00:00 IST 2016 */

Example - 2


SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
Date date = format.parse("31-JEN-2016");
System.out.println(date);

/*O/P---Exception in thread "main" java.text.ParseException: Unparseable date: "31-JEN-2016"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at Solution.main(Solution.java:21)    ...
 */

Here we can see the validation is pretty simple and straight forward. But let's see some other use cases and will decide whether the validation is really such straight forward ?

Example - 3

SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
Date date = format.parse("32-JAN-2016");
System.out.println(date);

/*O/P--- Mon Feb 01 00:00:00 IST 2016 */

Here you see even the input string is an invalid date but the formatter can parse it and returning the next valid date by incrementing the day. (from 32-JAN to 01-FEB).
Now you are confused that, "how can we validate in a correct way ?".

Here is the secret of SimpleDateFormat:

SimpleDateFormat extends java.text.DateFormat which having this below method
This above method uses the heuristics to interpret the given input. So make sure to disable 
this property by setting as formater.setLenient(false);

Example - 3 modified



Now it validated properly as we want.