2016-09-23 92 views
0

我发现了很好的功能,它验证了日期的格式和正确性String。我想升级它只验证>= 1900年。在Java中验证日期字符串时出现异常

所以这是我发现:

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")运行此功能。在解析年份Stringint时抛出NumberFormatException。这绝对不应该发生,因为ParseException应该先抛出,打破try {}块。

它看起来像从第一个清单验证不能正常工作,因为它接受每个"yyyy"部分以数字开头。然而,一切工作正常"12-12-xxxx"编辑"12-12-abcd")。

编辑:

停止投票了我的问题,而你正在阅读的焦点。问题很明显:为什么新的SimpleDateFormat(“dd-MM-yyyy”)。parse(“12-12-1xxx”)不会抛出ParseException?

+1

这是我的系统上工作正常,请检查您的输入,并使用最新的JDK –

+0

我可以发布一个快照(只是作为答案),但它没有任何意义,所以检查任何无效输入 –

+0

是的,它也在我的系统上工作。 –

回答

2

正如我从javadoc了解到的SimpleDateFormat将1作为一年的有效部分,并将解析它。相反,您可以尝试使用正则表达式验证日期。你可以找到一些例子在这里Regex to validate date format dd/mm/yyyy

+0

最后我们有人可以阅读。感谢您的解决方案! –

0

我检查你的功能,并找到下面的细节。

如果你将通过在主要功能12-12-1xxx那么你也将获得真正的,甚至当我打印日期输出是由df.parse(date)转换也不会返回false是10月10日00:00:00 GMT 2.

所以你不会得到任何时候分析异常为此,

建议

要么你被改变的异常或ParseException的使用也渔获NumberFormatException的下面。

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; 
    }*/ 
} 
+1

这并不能解释为什么当输入无效输入时不会抛出ParseException。此外:捕捉“Exception”是一种不好的做法,因为它包含可能出现的任何RuntimeException。 –

+0

检查这一个https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html你会明白为什么你没有得到错误,因为它会考虑这种类型的文本在日期以他们的标准 – Vickyexpert

+0

@LittleSanti这不是无效的输入,并为此我有一个解析日期也显示输出,如Java文档考虑它作为日期检查上面的链接 – Vickyexpert

1

parse方法的文档:

从给定字符串的开始解析文本,以生成一个日期。 该方法可能不使用给定字符串的整个文本。

由于不需要使用整个字符串,因此“12-12-1xxx”实际上被解析为“12-12-1”,并且您获得了第1年的日期。

而不是使用子的,你可以用解析方法的结果来获得一年。 getYear折旧并返回从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; 
    } 
} 
+0

感谢您解释为什么“解析”方法不会抛出异常。我想我会另外捕获NumberFormatException。无论如何,谢谢你的提议。 –

0

如果有人有兴趣的代码应该看起来怎么样,那就是:

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