Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does SimpleDateFormat.parse accept an invalid date string?

Tags:

java

date

I have a java code, that inputs date in a specific format.

static Date parseDate(String userInput){
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(userInput);
            System.out.println(date);
        }catch(ParseException pe){
            date=null;
            System.out.println("Not a valid date");
        }
        return date;
    }

Now I'm entering 2015-13-11 89:90:90 which is an invalid date. But it returns Thu Jan 14 18:31:30 IST 2016 as the date. Why is this so? How do I make it to return null as the date?

like image 441
inquisitive Avatar asked Jul 30 '15 22:07

inquisitive


2 Answers

From a glance of the javadocs, it seems to be using a lenient mode of parsing in which it accepts poorly formatted input:

Adding this line

format.setLenient(false);

after the initialization of your DateFormat object appears to fix it.

like image 174
Kyzderp Avatar answered Nov 11 '22 05:11

Kyzderp


I will attempt to explain why this is happening.

The date is different because the values which exceed their fields' maximum are rolled up into the next greater field.

I am not sure the order in which it is resolved, but here is what happens in general:

Given 2015-13-11 89:90:90

  1. The year is interpreted as 2015, that is set correctly. Currently 2015-01-01 00:00:00
  2. The month is interpreted as 13, 13 / MONTHS_IN_A_YEAR = 1, so a year is added and we set the month to 1 (13 months - 1 year). Currently 2016-01-01 00:00:00
  3. The date is interpreted as 11. This is correctly set. Currently 2016-01-11 00:00:00
  4. The hour is interpreted 89, 89 / HOURS_IN_A_DAY = 3, so 3 days are added and we set the hour to 17 (89 hours - 3 days). Currently 2016-01-14 17:00:00
  5. The minute is interpreted as 90, 90 / MINUTES_IN_A_HOUR = 1, so 1 hour is added and we set the minutes to 30 (90 minutes - 1 hour). Currently 2016-01-14 18:30:00
  6. The second is interpreted as 90, 90 / SECONDS_IN_A_MINUTE = 1, so 1 minute is added and we set the seconds to 30 (90 seconds - 1 minute).

This leaves us with 2016-01-14 18:31:30.

like image 40
Kyle Shrader Avatar answered Nov 11 '22 03:11

Kyle Shrader