Input: String
Output: Boolean indicating whether the provided date is in provided format
private static String DATE_FORMAT = "dd-MM-yyyy"; public boolean validateDate(String date) { try { DateFormat df = new SimpleDateFormat(DATE_FORMAT); df.parse(date); return true; } catch (ParseException e) { e.printStackTrace(); return false; } }
The following results were observed.
Input | Actual Output | Expected Output |
---|---|---|
01-01-9999 | true | true |
333-01-9999 | true | false |
As provided in the API documentation of DateFormat states
By default, parsing is lenient: If the input is not in the form used by this object's format method but can still be parsed as a date, then the parse succeeds. Clients may insist on strict adherence to the format by calling setLenient(false).
Thus the unexpected behavior while parsing the input '333-01-9999'. We now change the code to add
private static String DATE_FORMAT = "dd-MM-yyyy"; public boolean validateDate(String date) { try { DateFormat df = new SimpleDateFormat(DATE_FORMAT); df.setLenient(false); df.parse(date); return true; } catch (ParseException e) { e.printStackTrace(); return false; } }
The following results were observed.
Input | Actual Output | Expected Output |
---|---|---|
01-01-9999 | true | true |
333-01-9999 | false | false |
3a-01-9999 | false | false |
02-03-1@@@ | true | false |
02-03-18 | true | false |
And boom. The parsing of '02-03-1@@@' and '02-03-18' again provides us with an unexpected result. This seems to be a bug in the validation.
So I searched the Sun bug database. But strangely enough the bug has been rejected. The rationale provided is completely and utterly bull*&(#.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5055568
The comments by the Bug submitter have been ignored.
Suppose the input to the method is supposed to be '01-01-2010' and the user provides '01-01-2o10' then the data will be converted into the date 01-01-0002. This after the seeing the setLenient documentation which states that:-
Specify whether or not date/time parsing is to be lenient. 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.So the solution to this problem is to match the string using regular expression before validating with the parse method.
private static String DATE_FORMAT = "dd-MM-yyyy"; private String REGEX_DATE_FORMAT = "^(0[1-9]|[12][0-9]|3[01])[- ](0[1-9]|1[012])[- ]\\d\\d\\d\\d$"; public boolean validateDate(String date) { try { if(!Pattern.matches(REGEX_DATE_FORMAT, date)) { return false; } DateFormat df = new SimpleDateFormat(DATE_FORMAT); System.out.println(df.parse(date)); return true; } catch (ParseException e) { e.printStackTrace(); return false; } }
Input | Actual Output | Expected Output |
---|---|---|
01-01-9999 | true | true |
333-01-9999 | false | false |
3a-01-9999 | false | false |
02-03-1@@@ | false | false |
02-03-18 | false | false |
So we solve the problem.
Hoping some day java will include a simpler way of validation of dates.