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

日期驗證正則表達式大全:YYYY-MM-DD、DD/MM/YYYY 與閏年精確匹配

     編輯:PHP 相關知識

前言

日期格式驗證是表單處理的基本需求。本文提供三種實用的正則表達式方案:基礎格式檢查、嚴格邏輯驗證 (含月份天數與閏年)、歐式 DD/MM/YYYY 格式,並說明 PHP 實作注意事項。

方案一:基礎格式匹配 (YYYY-MM-DD)

僅檢查格式結構,不驗證日期邏輯合法性:

$pattern = '/^\d{4}-\d{1,2}-\d{1,2}$/';

$dates = ['2004-06-01', '2005-0x-10', '12-12-12', '2000-12-25 00:10:20', '2007-12-05'];

foreach ($dates as $date) {
    if (preg_match($pattern, $date, $matches)) {
        echo "符合格式: $date => 年={$matches[0]}, 月={$matches[1]}, 日={$matches[2]}<br>";
    } else {
        echo "<b>不符合格式: $date</b><br>";
    }
}

方案二:嚴格邏輯驗證 (含閏年、大小月)

精確匹配合法日期,包含:

  • 大月 (1,3,5,7,8,10,12) 31 天
  • 小月 (4,6,9,11) 30 天
  • 2 月平年 28 天、閏年 29 天
  • 閏年規則:能被 4 整除但不能被 100 整除,或能被 400 整除
$strictPattern = '/^(
    (?:
        # 非閏年
        \d{4}-(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01]) |
        \d{4}-(?:0[469]|11)-(?:0[1-9]|[12]\d|30) |
        \d{4}-02-(?:0[1-9]|1\d|2[0-8])
    ) |
    (?:
        # 閏年 2 月 29 日
        (?:\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29
    )
)$/x';

// 測試
$testDates = [
    '2023-02-28', '2023-02-29',  // 平年
    '2024-02-28', '2024-02-29',  // 閏年
    '2023-04-31', '2023-04-30',  // 小月
    '2023-13-01', '2023-00-10'   // 非法月份
];

foreach ($testDates as $d) {
    echo "$d: " . (preg_match($strictPattern, $d) ? '✓ 合法' : '✗ 不合法') . "<br>";
}

方案三:歐式格式 DD/MM/YYYY 或 D/M/YYYY

支援單雙位數日/月,同樣包含閏年邏輯:

$euPattern = '/^(
    (?:
        \d{4}[-/](?:0[13578]|1[02])[-/](?:0[1-9]|[12]\d|3[01]) |
        \d{4}[-/](?:0[469]|11)[-/](?:0[1-9]|[12]\d|30) |
        \d{4}[-/]02[-/](?:0[1-9]|1\d|2[0-8])
    ) |
    (?:
        (?:\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)[-/]02[-/]29
    )
)$/x';

PHP 內建函式替代方案 (推薦)

正則表達式雖強大但難維護。PHP 提供更可靠的內建驗證:

// 1. checkdate() - 最簡單可靠
function isValidDate($year, $month, $day) {
    return checkdate((int)$month, (int)$day, (int)$year);
}

// 2. DateTime::createFromFormat() - 解析並驗證字串
function validateDateString($dateStr, $format = 'Y-m-d') {
    $dt = DateTime::createFromFormat($format, $dateStr);
    return $dt && $dt->format($format) === $dateStr;
}

// 3. 結合 strtotime() (需注意鬆散解析)
function looseValidate($dateStr) {
    $ts = strtotime($dateStr);
    return $ts !== false && date('Y-m-d', $ts) === $dateStr;
}

// 測試
var_dump(isValidDate(2024, 2, 29));      // true (閏年)
var_dump(isValidDate(2023, 2, 29));      // false
var_dump(validateDateString('2024-02-29')); // true
var_dump(validateDateString('2024-13-01')); // false

效能比較與選擇建議

方法優點缺點適用場景
正則嚴格版單一表達式、無函式呼叫極難閱讀維護、效能較差純前端 JS、資料庫 CHECK 條件
checkdate()核心優化、語義清晰、正確處理閏年需先拆分年月日PHP 後端驗證首選
DateTime::createFromFormat支援多種格式、自動標準化物件建立開銷略大解析使用者輸入字串

前端 JavaScript 實作

瀏覽器原生支援 type="date" 輸入框自動驗證,或使用 checkdate 邏輯移植:

function isValidDateJS(year, month, day) {
    const d = new Date(year, month - 1, day);
    return d.getFullYear() === year && d.getMonth() === month - 1 && d.getDate() === day;
}

// HTML5 原生驗證
// <input type="date" required>  // 瀏覽器自動檢查格式與合法性

總結

日期驗證首選 PHP 內建 checkdate() 或 DateTime::createFromFormat(),正確、可讀、可維護。正則表達式適合無法使用程式語言函式的場景 (如資料庫約束、前端純 JS 環境)。嚴格版正則雖複雜但展示了閏年邏輯的完整實現,理解其原理有助於深入掌握日期運算規則。

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