![](/img/trans.png)
[英]NumberFormatException while parsing date with SimpleDateFormat.parse()
[英]Is it ncessary to use Regex to check date sanity in addition to SimpleDateFormat.parse?
我看過下面的代碼,我對這里使用 Regex 感到困惑。 這個 checkDateSanity 方法的要求是:
DATE 格式為 dd.MM.yyyy。 (警告:日期必須存在!!)
private boolean checkDateSanity(String dateString) {
if (Pattern.matches("[0-3][0-9].[0-1][0-9].[0-9]{4}", dateString)) {
try {
DateFormat df = new SimpleDateFormat(DATE_FORMAT);
df.setLenient(false);
df.parse(dateString);
return true;
} catch (ParseException e) {
return false;
}
}
return false;
}
我已經閱讀了有關類似主題的這篇文章How to sanity check a date in Java ,其中答案只是使用
try {
DateFormat df = new SimpleDateFormat(DATE_FORMAT);
df.setLenient(false);
df.parse(dateString);
return true;
} catch (ParseException e) {
return false;
}
我做了一些隨機測試,無論有沒有它,Regex 都沒有任何區別。 有沒有更深層次的理由讓 Regex 在這里檢查? 想降低計算成本? 如果是這樣的話,真的值得嗎?
定義“有效”。
例如,正則表達式允許在第 19 個月的第 39 天以及第 0 個月的第 0 天:根據它, 39-19-0000
是有效日期,但1-1-2020
不是(僅01-01-2020
將是)。
SDF 是舊的 API ,您不應該使用(使用java.time
),但就這段代碼而言,寬大已關閉,因此它不接受39-19-0000
,盡管它會接受1-1-2020
。
將兩者結合起來會讓你得到最嚴格的要求,但它確實讓人感到復雜。 接受1-1-2020
是否有特別令人發指的問題?
但請注意這個巨大的問題:年份混亂。 1-1-99
將使用帶有模式dd.MM.yyyy
的.setLenient(false)
SDF 進行解析,並被解釋為 99 年的 1 月 1 日,即羅馬帝國時期的某個時候(不像王子歌)。
僅出於這個目的,該正則表達式就非常有用; 如果通過了 2 位數年份,您可以使用正則表達式出錯,因為 SDF 不能拒絕這種輸入。
那些舊的日期 API 非常糟糕。 他們很爛。 不要使用它們。 更新您的 IDE,將SimpleDateFormat
標記為非法。 這是 java 時間 package,做你想做的事。 請注意,SDF 返回一個java.util.Date
,這是一個撒謊的騙子:它代表時間的瞬間並且沒有代表日期的業務。 它真的沒有 - 這就是所有各種.getYear()
等方法都被棄用的原因。
LocalDate x = LocalDate.parse("01.01.1999", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
System.out.println(x);
> 1999-01-01
// Awesome. It's an actual _DATE_ and not a timestamp where timezones
// can mess everything up.
LocalDate x = LocalDate.parse("01.01.99", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
> Exception in thread "main" java.time.format.DateTimeParseException: Text '01.01.1999' could not be parsed
// perfect. it crashes, as it should.
LocalDate x = LocalDate.parse("1.1.1999", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
> Exception in thread "main" java.time.format.DateTimeParseException: Text '01.01.1999' could not be parsed
// if you want `1.1.1999` to crash, well, you can.
LocalDate x = LocalDate.parse("1.1.1999", DateTimeFormatter.ofPattern("d.M.yyyy"));
System.out.println(x);
> 1999-01-01
// but you don't have to. with just `d`, 1 parses as 1, so does 01.
您也可以使用yy
go ,這迫使您只使用 2 位數字; 它們都被解釋為 20xx。 (1.1.99 是 2099-01-01)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.