首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

超強日期時間驗證正則:精準校驗閏年、月份天數與時間格式

     編輯:更多程式設計知識

前言

日期格式驗證看似簡單,實則暗藏玄機:大小月天數不同、閏年 2 月 29 日判斷邏輯複雜。網上流傳一個「特牛」的正則表達式,能在單一模式中完整覆蓋 YYYY-MM-DD 格式的所有邊界條件,甚至延伸支援時間部分。本文拆解其結構,助你理解並靈活應用。

純日期版正則(YYYY-MM-DD)

^(
  ((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01])      |  # 31天月份
  ((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30)      |  # 30天月份
  ((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8])                        |  # 2月平年1-28日
  (((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29)
)$

邏輯分層解析

  1. 年份範圍:(1[6-9]|[2-9]\d)\d{2} → 1600-9999 年。
  2. 31 天月份:0?[13578]|1[02](1,3,5,7,8,10,12),日期 0?[1-9]|[12]\d|3[01]。
  3. 30 天月份:0?[13456789]|1[012](排除 2 月),日期 0?[1-9]|[12]\d|30。
  4. 2 月平年:0?2 月份,日期 0?[1-9]|1\d|2[0-8](1-28 日)。
  5. 2 月閏年 29 日:最複雜分支,閏年判斷邏輯:
    • 普通閏年:年份後兩位能被 4 整除但非 00 → (0[48]|[2468][048]|[13579][26])。
    • 世紀閏年:前兩位能被 4 整除 → (16|[2468][048]|[3579][26])00。

日期時間擴展版(含 HH:mm:ss)

^(
  ...以上日期部分...
)
(20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$

時間部分解析

  • 小時:20|21|22|23|[0-1]?\d → 0-23(允許單數字或雙數字)。
  • 分鐘/秒:[0-5]?\d → 0-59。

使用建議與局限

  • 優點:單一正則完成全邏輯驗證,無需額外代碼判斷閏年,適合前端快速校驗或數據庫 CHECK 約束。
  • 缺點:可讀性極低,維護困難;正則引擎回溯風險較高,極長輸入可能效能問題。
  • 最佳實踐:生產環境建議「正則校驗格式 + 代碼邏輯校驗有效性」雙重保險。例如 JS 中 new Date(str) 配合比對年月日,或使用成熟庫(Moment.js, date-fns, Luxon)。
  • 年份下限:該正則從 1600 年開始,若需支援更早年份需調整年份模式。

結語

這個「特牛」正則展示了正則表達式處理複雜業務邏輯的極致能力,但也提醒我們:能用正則不代表都該用正則。理解其原理有助於閱讀遺留代碼,新項目優先選擇可維護性更強的專用日期庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved