SimpleDateFormat无法按预期工作。

5

我尝试使用这个函数,但它在输入 '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;
    }

它需要 201 作为年份。如果你把所有字母都放在年份的位置上,它将无法解析。因为它期望在年份的位置上只有 1 位数字。 - SatyaTNV
它期望在“年份”位置至少有一个数字。 - SatyaTNV
@Reimeus:SimpleDateFormat并不会忽略字母,它只是不会消耗整个字符串。这里有一个它不忽略字母的例子:http://ideone.com/gnbTwy - T.J. Crowder
@Danielson:OP可以随意格式化他们的代码。 - T.J. Crowder
@Reimeus:“简单地忽略字母”这种说法是不正确的,然而 :-) - T.J. Crowder
1个回答

12

DateFormat#parse 不一定使用给定字符串的全部内容:

从给定字符串的开头解析文本以生成日期。 该方法可能不使用给定字符串的全部文本。

(我强调的部分)

SimpleDateFormat 的文档告诉我们,yyyy 并不一定意味着需要四个数字来表示一年:

年份:

...

  • 对于解析而言,如果模式字母的数量大于2,则年份按照字面值进行解释,而不考虑数字的数量。因此,使用模式 "MM/dd/yyyy""01/11/12" 解析为公元 12 年 1 月 11 日。

因此,它正确地(如果可能让人感到惊讶)将该字符串解析为公元 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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接