简体   繁体   中英

SimpleDateFormat.parse not detecting incorrect date

Been experimenting with SimpleDateFormat. One thing I do not understand : why does the following returns ok ?

String pattern = "MM/dd/yyyy";
SimpleDateFormat format = new SimpleDateFormat(pattern);

String input = "2023/03/22";
Date d = null;

try {
    d = format.parse(input);
} catch (ParseException e) {
    System.out.println("nok");
}

System.out.println("ok");

Date returned is absurd too : Fri Jul 03 00:00:00 CET 190

Any explanation is greatly appreciated!

Let's spell it out for those readers who want it all in the answer:

format.setLenient(false) is what you need.

Here's how you might do it. I agree with AxelH: You should be using JDK8, java.time package and LocalTime :

import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateFormatTest {

    @Test(expected = ParseException.class)
    public void testSetLenient_IncorrectDateInput() throws ParseException {
        // setup
        String input = "2023/03/22";
        String pattern = "MM/dd/yyyy";
        DateFormat format = new SimpleDateFormat(pattern);
        format.setLenient(false);
        // exercise and assert
        format.parse(input);
    }
}

Any explanation is greatly appreciated!

here we go: the explanation is simple:

this format "MM/dd/yyyy" is pretty simple about how is what, the object is expecting a month day year information to be parsed.

so you are giving this "2023/03/22" , then the 1st this is wrong here is that the moth (which should be between 1 and 12) is holding the value 2023, this is interpreted by the parser as the month 12 + 2011 extra months after that.

day 03 is ok, and year 22 means exactly that, the year 22 After Christos birth.

so your resulting date is

the valid data plus the weird offset, ie

12/03/0022 + 2011 months.

now 2011 months is the same as: 167 years and 7 months so we do the math:

12 03 of the year 22 plus 167 years and 7 months... then you get

Fri Jul 03 00:00:00 CET 190


the solution:

format.setLenient(boolean);

check the doc to see what exception will be thrown in such case....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM