簡體   English   中英

(Re)使用DateTimeFormatter解析日期范圍或將DateTimeFormatter與正則表達式混合

[英](Re)Use DateTimeFormatter for parsing date ranges or mix DateTimeFormatter with regex

我有以下字符串表示我需要解析的日期范圍:

2018-10-20:2019-10-20

它由2個ISO日期字符串組成,中間用:

通過將重復的日期范圍與其他文本混合,可以使字符串變得更復雜。 這可以通過正則表達式來完成。

但是,鑒於最新的Java具有日期/時間支持,因此在這里和其他地方的大多數編碼人員都對它感到欣喜若狂,是否有可能使用LocalDate的解析器或自定義的DateTimeFormatter來識別我的String中的候選位。 ISO日期並捕獲它們?

更好的是,如何從DateTimeFormatter (假定有一個ISO日期的正則表達式)中提取驗證正則表達式,並將其與我自己的正則表達式合並/編譯,以用於其余的String。

當我可能在Java中已經有一個正則表達式可以這樣做並且我只是重新使用它時,我只是在我的代碼中編寫另一個ISO日期正則表達式感到不舒服。

請注意,我不要求輸入正則表達式。 我可以的

另請注意,我的示例字符串可以包含其他日期/時間格式,例如帶時區和毫秒以及所有的口哨聲。

實際上, DateTimeFormatter沒有內部正則表達式。 使用CompositePrinterParser ,后者再使用DateTimePrinterParser實例數組 (這是DateTimeFormatterBuilder內部接口 ),其中每個實例負責解析/格式化特定字段。

海事組織,正則表達式不是此處的最佳方法。 如果您知道所有日期都由:分隔,為什么不簡單地拆分字符串並嘗試分別解析各個部分呢? 像這樣:

String dates = // big string with dates separated by :

DateTimeFormatter parser = // create a formatter for your patterns
for (String s : dates.split(":")) {
    parser.parse(s); // if "s" is invalid, it throws exception
}

如果您只想驗證字符串,則如上所述調用parse就足夠了-如果字符串無效,它將引發異常。

要支持多種格式,可以使用DateTimeFormatterBuilder::appendOptional 例:

DateTimeFormatter parser = new DateTimeFormatterBuilder()
    // full ISO8601 with date/time and UTC offset (ex: 2011-12-03T10:15:30+01:00)
    .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
    // date/time without UTC offset (ex: 2011-12-03T10:15:30)
    .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    // just date (ex: 2011-12-03)
    .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE)
    // some custom format (day/month/year)
    .appendOptional(DateTimeFormatter.ofPattern("dd/MM/yyyy"))
    // ... add as many you need
    // create formatter
    .toFormatter();

可以支持多種格式的正則表達式(如您所說,“其他日期/時間格式,例如,時區和毫秒以及所有的口哨聲”),但是該正則表達式不能很好地驗證日期-例如零日,天> 30並非對所有月份都有效,在非valid年2月29日,分鍾> 60等。

DateTimeFormatter將驗證所有這些棘手的細節,而regex僅保證您將數字和分隔符放在正確的位置,並且不會驗證值。 因此,不管正則表達式如何,您都必須解析日期(恕我直言,在這種情況下,使正則表達式的使用非常無用)。

正則表達式+日期解析器是正確的選擇。

您必須自己編寫正則表達式,因為日期解析器未使用正則表達式。

您可以選擇正則表達式是否簡單,例如\\d{2}表示月份,並讓日期解析器驗證數字范圍,或者如果它必須更嚴格,例如(?:0[1-9]|1[0-2]) 01 - 12 )。 正則表達式中不應進行28天,30天和31天之類的范圍檢查。 讓日期解析器處理該問題,並且由於某些值范圍由日期解析器處理,因此不妨讓它處理所有這些值范圍,即,簡單的正則表達式就可以了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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