验证 Java 中的日期字符串时出现异常

Exception while validating a date string in Java

我发现了一个很好的函数,它可以验证日期的格式和正确性 String。我想升级它以仅验证 >= 1900 年。

这就是我的发现:

public boolean isDateValid(String date) {
    try {
        DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
        df.setLenient(false);
        df.parse(date);
        return true;
    } catch (ParseException e) {
        return false;
    }
}

这是我的升级版:

public boolean isDateValid(String date) {
    try {
        DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
        df.setLenient(false);
        df.parse(date);
        Integer year = Integer.parseInt(date.substring(6, 10));
        if (year>= 1900)
            return true;
        else
            return false;
    } catch (ParseException e) {
        return false;
    }
}

所以我没有返回 true,而是检查 year 变量是否大于或等于 1900。问题是当我 运行 这个函数与 "12-12-1xxx" (编辑:或"12-12-1abc")。将年份 String 解析为 int 时抛出 NumberFormatException。这绝对不应该发生,因为 ParseException 应该首先抛出,打破 try {} 块。

第一个列表的验证似乎无法正常工作,因为它接受每个以数字开头的 "yyyy" 部分。然而,对于 "12-12-xxxx"edit:或 "12-12-abcd"),一切正常。

编辑:

在阅读时停止对我的问题投反对票并集中注意力。问题很明确:为什么 new SimpleDateFormat("dd-MM-yyyy").parse("12-12-1xxx") 不抛出 ParseException?

我已经检查了你的功能,并找到了以下详细信息。

如果你在 main 函数中传递 12-12-1xxx 那么你也会得到 true 它不会 return false 即使当我打印日期输出时由 df.parse(date) 转换为 Oct 10 00:00:00 GMT 2.

所以你不会在任何时候得到解析异常,

建议

您可以通过 Exception 更改 ParseException,也可以像下面那样对 NumberFormatException 使用 catch。

 public boolean isDateValid(String date) {
    try {
        DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
        df.setLenient(false);
        df.parse(date);
        Integer year = Integer.parseInt(date.substring(6, 10));
        if (year>= 1900)
            return true;
        else
            return false;
    } catch (Exception e) { // Use Exception or if you want ParseException then use below commented code
        return false;
    }
    /*catch (NumberFormatException nfe) { // Use this if you use ParseException
        return false;
    }*/
 }

正如我从 javadoc 中了解到的那样,SimpleDateFormat 会将 1 作为一年中的有效部分并将对其进行解析。相反,您可以尝试使用正则表达式来验证日期。您可以在此处找到一些示例 Regex to validate date format dd/mm/yyyy

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.

因为不需要使用整个字符串,所以“12-12-1xxx”实际上被解析为“12-12-1”,得到的是1年的日期。

您可以使用解析方法的结果来获取年份,而不是使用子字符串。 getYear 已折旧,returns 是从 1900 开始的偏移量,因此您可能希望先转换为 CalendarLocalDate

public boolean isDateValid(String date) {
    try {
        DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
        df.setLenient(false);
        Date parsed = df.parse(date);
        int year = parsed.getYear() + 1900;
        if (year >= 1900)
            return true;
        else
            return false;
    } catch (ParseException e) {
        return false;
    }
}

如果有人对代码的外观感兴趣,请看这里:

public boolean isDateValid(String date, String format) {
    if (date.length()!=format.length())
        return false;
    try {
        DateFormat df = new SimpleDateFormat(format);
        df.setLenient(false);

        df.parse(date); // exception is not thrown if day and month is
                        // correct AND the first char of year is a digit

        // so if we have correct day and correct month
        // and we know the year has 4 chars we can try to parse it
        Integer year = Integer.parseInt(date.substring(6, 10));

        if (year>= 1900 && year<=2015) // here we know that the year is 4 digit integer
            return true;               // and we can limit it
        else
            return false;

    } catch (ParseException e) {
        return false;
    } catch (NumberFormatException e) {
        return false;
    }
}