5

I try to use this function but it doesn't work with this case '12/05/201a' somebody knows why happen this?

In my test I use this System.out.println(isThisDateValid("12/05/201a", "dd/MM/yyyy")); and the answer was true but I'm expected the result would be false because year contains letters.

 public static boolean isThisDateValid(String dateToValidate, String dateFromat)
    {

        if (dateToValidate == null)
        {
            return false;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
        sdf.setLenient(false);

        try
        {

            //if not valid, it will throw ParseException
            Date date = sdf.parse(dateToValidate);
            System.out.println(date);

        } catch (ParseException e)
        {

            e.printStackTrace();
            return false;
        }

        return true;
    }
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
kakashy
  • 714
  • 9
  • 24

1 Answers1

12

DateFormat#parse doesn't necessarily use the entire string:

Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.

(my emphasis)

SimpleDateFormat's docs tell us that yyyy doesn't necessarily mean it will require four digits for a year:

Year:

...

  • For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.

So it's correct (if possibly surprising) that it parses that string in the year 201.

You can use parse(String,ParsePosition) to figure out whether the entire string has been consumed, or validate it with a regular expression before parsing. Here's a version that will check that the whole string has been parsed, and not just the first characters:

public static boolean isThisDateValid(String dateToValidate, String dateFormat) {
    if (dateToValidate == null) {
        return false;
    }

    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    sdf.setLenient(false);

    ParsePosition position = new ParsePosition(0);
    Date date = sdf.parse(dateToValidate, position);
    return date != null && position.getIndex() == dateToValidate.length();
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255