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

PHP 取得指定年月份天數:閏年判斷與實作技巧

     編輯:PHP 相關知識

PHP 計算月份天數:閏年邏輯與最佳實踐

在日期相關運算中,「某年某月有幾天」是基礎又關鍵的需求。PHP 內建 cal_days_in_month() 雖方便,但了解其底層邏輯有助於處理特殊情境(如不支援 Calendar 擴充套件的環境、需自訂曆法規則)。本文解析經典的 daysOfMonth() 實作並提供現代化改寫。

原始實作分析

public function daysOfMonth($year = NULL, $month = NULL) {
    if ($year === NULL) {
        $year = $this->getPart('yy');
    }
    if ($month === NULL) {
        $month = $this->getPart('mm');
    }
    if ($month == 2) {
        if (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0)
            $result = 29;
        else
            $result = 28;
    } elseif ($month == 4 || $month == 6 || $month == 9 || $month == 11)
        $result = 30;
    else
        $result = 31;
    return $result;
}

核心邏輯:閏年判斷規則

格里曆閏年規則:

  1. 西元年分能被 4 整除 → 閏年(2 月 29 天)
  2. 例外:能被 100 整除 → 平年(2 月 28 天)
  3. 再例外:能被 400 整除 → 閏年(2000 年是閏年,1900 年不是)

程式碼中 ($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0 完美對應此規則。

現代化改寫(PHP 7.1+)

function getDaysInMonth(int $year, int $month): int {
    // 參數驗證
    if ($month < 1 || $month > 12) {
        throw new InvalidArgumentException('月份必須在 1-12 之間');
    }
    if ($year < 1 || $year > 9999) {
        throw new InvalidArgumentException('年份超出範圍');
    }

    // 使用內建函數(需 calendar 擴充套件)
    if (function_exists('cal_days_in_month')) {
        return cal_days_in_month(CAL_GREGORIAN, $month, $year);
    }

    // 手動實作(相容無擴充套件環境)
    $daysInMonth = [1=>31, 3=>31, 4=>30, 5=>31, 6=>30, 7=>31, 8=>31, 9=>30, 10=>31, 11=>30, 12=>31];
    if ($month === 2) {
        $isLeap = ($year % 4 === 0 && $year % 100 !== 0) || ($year % 400 === 0);
        return $isLeap ? 29 : 28;
    }
    return $daysInMonth[$month];
}

DateTime 物件導向寫法(推薦)

function getDaysInMonthOOP(int $year, int $month): int {
    $date = new DateTime("{$year}-{$month}-01");
    $date->modify('last day of this month');
    return (int)$date->format('d');
}

// 使用範例
echo getDaysInMonthOOP(2024, 2); // 29
echo getDaysInMonthOOP(2023, 2); // 28

效能比較與建議

方法相依性速度推薦場景
cal_days_in_month()calendar 擴充套件最快高頻呼叫、生產環境
DateTime 物件內建 (PHP 5.2+)中等物件導向專案、需時區處理
手動陣列查表零相依快嵌入式/舊版環境、教學用途

常見陷阱提醒

  • 輸入月份為字串 '08' 時,intval() 會正確轉為 8,但 (int)'08' 在 PHP 8.1+ 可能拋出非標準數字警告
  • 年份 0 不存在(西元年從 1 年開始),傳入 0 會導致錯誤判斷
  • 儒略曆轉格里曆(1582 年)前的日期需特殊處理,一般商業應用可忽略
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved