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 !!

Leave a Comment

  1. Hi, I’m getting below validation error while unmarshaling my xml file

    cvc-datatype-valid.1.2.1: ‘2019-02-19T14:34:40+03’ is not a valid value for ‘dateTime’.

    Please help me for resolve it.

    Thanks,
    Pawan

    Reply
  2. Even if you use setLenient to FALSE, in the cases that the intervals are acceptal but the format is not, the parse will result in success.
    To avoid it, use format over the parse result Date and compare with “equals” the initial String date.

    Reply
  3. I tried to parse this date “2014-100-11 22:53:45” and guess what it parsed!!!!….no error!!!!

    and also sometimes my simpledateformatter returns date in format like ‘2014-0011-20 21:53:45 ‘. How it can be?

    Reply
  4. Hi Lokesh,
    JAXB is not populating the dateTime fields with joda DateTime values
    @XmlElement(name=”joindate”)
    private DateTime joinDate;

    I don’t see any error in the log as well because it is generating as empty tag.

    Reply

Leave a Comment

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