簡體   English   中英

除了 SimpleDateFormat.parse 之外,是否還需要使用 Regex 來檢查日期完整性?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM