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

PHP checkdate() 函數驗證日期合法性完整指南

     編輯:PHP 綜合知識

為什麼需要驗證日期?

用戶輸入的日期(如生日、預約時間)常包含非法值:2 月 30 日、閏年 2 月 29 日邏輯錯誤、月份超出 12 等。直接寫入資料庫會導致約束報錯或數據污染。PHP 內建 checkdate() 函數專門解決此問題,無需手寫複雜正則或閏年判斷邏輯。

函數簽名與參數

checkdate(int $month, int $day, int $year): bool
  • $month:月份 (1-12)
  • $day:日期 (1-31,根據月份/年份自動判斷上限)
  • $year:年份 (1-32767,受系統整數範圍限制)
  • 返回值:合法返回 true,否則 false

核心邏輯:自動處理閏年與月份天數

checkdate() 內部實現了完整的格里高利曆規則:

  • 1、3、5、7、8、10、12 月:31 天
  • 4、6、9、11 月:30 天
  • 2 月:平年 28 天,閏年 29 天
  • 閏年規則:能被 4 整除但不能被 100 整除,或能被 400 整除

實戰代碼範例

<?php
function validate_date_input(int $month, int $day, int $year): array {
    $result = [
        'valid' => false,
        'date'  => null,
        'error' => '',
    ];

    // 1. 基礎範圍檢查(可選,checkdate 內部已處理)
    if ($year < 1 || $year > 32767 || $month < 1 || $month > 12 || $day < 1 || $day > 31) {
        $result['error'] = '參數超出合理範圍';
        return $result;
    }

    // 2. 核心驗證
    if (checkdate($month, $day, $year)) {
        $result['valid'] = true;
        // 生成標準日期字符串
        $result['date'] = sprintf('%04d-%02d-%02d', $year, $month, $day);
    } else {
        $result['error'] = '日期不存在(如 2月30日、非閏年2月29日等)';
    }
    return $result;
}

// 測試用例
$test_cases = [
    [2, 29, 1900], // 非閏年(1900 不能被 400 整除)
    [2, 29, 2000], // 閏年(能被 400 整除)
    [2, 29, 2100], // 非閏年(能被 100 整除但不能被 400 整除)
    [4, 30, 2008], // 合法
    [4, 31, 2008], // 4 月無 31 日
    [13, 1, 2024], // 月份非法
    [1, 0, 2024],  // 日期為 0
];

foreach ($test_cases as [$m, $d, $y]) {
    $res = validate_date_input($m, $d, $y);
    $status = $res['valid'] ? '✅ 合法' : '❌ 非法';
    echo "{$y}-{$m}-{$d} => {$status} ";
    if (!$res['valid']) echo "原因: {$res['error']}";
    echo "\n";
}

輸出結果

1900-2-29 => ❌ 非法 原因: 日期不存在(如 2月30日、非閏年2月29日等)
2000-2-29 => ✅ 合法
2100-2-29 => ❌ 非法 原因: 日期不存在(如 2月30日、非閏年2月29日等)
2008-4-30 => ✅ 合法
2008-4-31 => ❌ 非法 原因: 日期不存在(如 2月30日、非閏年2月29日等)
2024-13-1 => ❌ 非法 原因: 參數超出合理範圍
2024-1-0 => ❌ 非法 原因: 參數超出合理範圍

常見應用場景

場景代碼片段
表單驗證(Laravel/CodeIgniter/原生)'birthday' => 'required|date_format:Y-m-d|checkdate' (需自定義規則調用 checkdate)
日期選擇器前端回傳值二次校驗前端攔截不代表後端可信,必須服務端再次 checkdate()
導入 Excel/CSV 日期列清洗遍歷行,拆分年月日調用 checkdate(),標記異常行
生成合法日期範圍(如下拉選單)雙層循環年月,內層 for($d=1;$d<=31;$d++) if(checkdate($m,$d,$y)) $days[]=$d;

進階:結合 DateTime 類進行更豐富驗證

function validate_date_advanced(string $date_str, string $format = 'Y-m-d'): ?DateTime {
    $dt = DateTime::createFromFormat($format, $date_str);
    // createFromFormat 遇到 2024-02-31 會自動溢出變成 2024-03-02,需額外校驗
    if ($dt === false) return null;
    // 嚴格模式:格式化後必須與原字符串一致(排除溢出情況)
    if ($dt->format($format) !== $date_str) return null;
    // 額外業務邏輯:如不能早於今天、不能晚於 100 年後等
    if ($dt < new DateTime('today')) return null;
    return $dt;
}

總結

  • checkdate() 是 PHP 官方提供的最權威、最高效的日期合法性檢查函數。
  • 自動處理閏年、大小月,無需手寫邏輯。
  • 參數為獨立的年月日整數,配合表單拆分字段極其方便。
  • 配合 DateTime::createFromFormat() 可實現字符串格式與邏輯的雙重驗證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved