Java Strict Date Validation – SimpleDateFormat.setLenient()

All of us have come across situations when we have to parse user input for validation. Other fields such as text or numeric are rather easy, but Java date validation is a little bit difficult, and a small error can leave the application in an unstable state.

1. Java Date Validation with SimpleDateFormat.parse()

Usually, SimpleDateFormat.parse() method is used for validation. If parse() method is able to parse the date, then it is considered that the input is valid. Well, it might be incorrect.

private static final String DATE_PATTERN = "MM/dd/yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);

//Lenient conversion result in unexpected output
Date d = sdf.parse("2012/12/17");
System.out.println(d);

Program output:

Wed Aug 12 00:00:00 GMT+05:30 184

1.1. What went wrong?

The above date validation is strange for two reasons. First, it should have flagged the validation error, and second, the date object obtained is completely useless. So, what went wrong here?

Well, the error is in parsing logic. The parse() method uses the positions of pattern keywords in DATE_PATTERN and uses it to parse the input string. It is not intelligent by default to use the right characters for parsing, and it uses what comes in its way (even slashes).

2. Correct way to validate a date with SimpleDateFormat.setLenient()

The solution is to use SimpleDateFormat.setLenient() method to bring the missing intelligence. Look at the strict date validation example given below:

private static final String DATE_PATTERN = "MM/dd/yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);

sdf.setLenient(false);

//Lenient conversion result in unexpected output
Date d = sdf.parse("2012/12/17");
System.out.println(d);

Program output.

java.text.ParseException: Unparseable date: "2012/12/17"
 at java.text.DateFormat.parse(DateFormat.java:337)
 at com.howtodoinjava.dateTest.TestSetLenient.main(TestSetLenient.java:33)

So, clearly setting setLenient(false); corrects the parsing behavior of SimpleDateFormat.

We can verify the correct parsing by passing a valid date in the required pattern.

private static final String DATE_PATTERN = "MM/dd/yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);

sdf.setLenient(false);

//Lenient conversion result in unexpected output
Date d = sdf.parse("12/17/2012");
System.out.println(d);

Program output.

Mon Dec 17 00:00:00 GMT+05:30 2012

3. Default leniency behavior in Calendar class

Source – http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html

Calendar class has two modes for interpreting the calendar fields, lenient and non-lenient. When a calendar is in lenient mode, it accepts a wider range of calendar field values than it produces. When a calendar recomputes field values for return by get(), all of the calendar fields are normalized.

For example, a lenient GregorianCalendar interprets “MONTH = JANUARY and DAY_OF_MONTH = 32” as February 1, which is incorrect.

When a Calendar is in non-lenient mode, it throws an exception if there is any inconsistency in its calendar fields. For example, a GregorianCalendar always produces DAY_OF_MONTH values between 1 and the length of the month. A non-lenient GregorianCalendar throws an exception upon calculating its time or calendar field values if any out-of-range field value has been set.

Default is lenient mode.

In this Java date validation example, we learned how to convert string to a particular date format in Java. And fail for other date patterns.

Happy Learning !!

Comments

Subscribe
Notify of
guest
9 Comments
Most Voted
Newest Oldest
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