SimpleDateFormat 没有按预期工作

SimpleDateFormat doesn't work as expected

我尝试使用此功能,但它不适用于“12/05/201a”这种情况,有人知道为什么会这样吗?

在我的测试中,我使用了这个 System.out.println(isThisDateValid("12/05/201a", "dd/MM/yyyy"));,答案是 true,但我预计结果会是错误的,因为年份包含字母。

 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;
    }

DateFormat#parse 不一定使用整个字符串:

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.

(我的重点)

SimpleDateFormat's docs 告诉我们 yyyy 并不一定意味着一年需要四位数:

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.

所以它在 201 年解析该字符串是正确的(如果可能令人惊讶的话)。

您可以使用parse(String,ParsePosition)判断整个字符串是否已经被消费,或者在解析前用正则表达式验证它。这是一个版本,它将检查整个字符串是否已被解析,而不仅仅是第一个字符:

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();
}