2016-09-23 89 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; 
    } 
}