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

PHP 日期日曆工具函數集:月曆矩陣、週/月範圍、相對時間篩選

     編輯:PHP 綜合知識

函數一:生成月曆矩陣 (二維陣列,含空白佔位)

輸入任一日期,輸出該月日曆矩陣,每週為一子陣列,索引 0-6 對應 週日-週六,無日期位置為 null。

 $v ?? '·', $week)) . "\n";
}
/* 輸出 (2024/02 從週四開始)
· · · · 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 · ·
*/
?>

函數二:取得月份起迄日期時間 (含時分秒)

函數三:取得週範圍 (週一至週日,ISO-8601)

 'Y-m-d H:i:s', 'end' => 'Y-m-d H:i:s']
 */
function getWeekRange(string $date): array {
    $ts = strtotime($date);
    // ISO-8601: 週一=1 ... 週日=7
    $dow = (int)date('N', $ts);

    $startTs = $ts - ($dow - 1) * 86400;
    $endTs = $ts + (7 - $dow) * 86400;

    return [
        'start' => date('Y-m-d 00:00:00', $startTs),
        'end'   => date('Y-m-d 23:59:59', $endTs),
    ];
}

// 範例
print_r(getWeekRange('2024-02-15')); // 週四
/* Array
(
    [start] => 2024-02-12 00:00:00 (週一)
    [end]   => 2024-02-18 23:59:59 (週日)
)
*/
?>

函數四:相對時間篩選器 (昨天、本週、上週、本月、上月...)

 'Y-m-d H:i:s', 'end' => 'Y-m-d H:i:s']
 */
function getRelativeRange(int $code): array {
    $now = new DateTime();
    $start = clone $now;
    $end = clone $now;

    switch ($code) {
        case 1: // 昨天
            $start->modify('-1 day')->setTime(0,0,0);
            $end->modify('-1 day')->setTime(23,59,59);
            break;
        case 2: // 本週 (週一~週日)
            $start->modify('this week Monday')->setTime(0,0,0);
            $end->modify('this week Sunday')->setTime(23,59,59);
            break;
        case 3: // 上週
            $start->modify('last week Monday')->setTime(0,0,0);
            $end->modify('last week Sunday')->setTime(23,59,59);
            break;
        case 4: // 上上週
            $start->modify('-2 week Monday')->setTime(0,0,0);
            $end->modify('-2 week Sunday')->setTime(23,59,59);
            break;
        case 5: // 本月
            $start->modify('first day of this month')->setTime(0,0,0);
            $end->modify('last day of this month')->setTime(23,59,59);
            break;
        case 6: // 上月
            $start->modify('first day of last month')->setTime(0,0,0);
            $end->modify('last day of last month')->setTime(23,59,59);
            break;
        default:
            throw new \InvalidArgumentException("Unknown range code: $code");
    }

    return [
        'start' => $start->format('Y-m-d H:i:s'),
        'end'   => $end->format('Y-m-d H:i:s'),
    ];
}

// 使用範例:SQL WHERE 子句產生
$range = getRelativeRange(2); // 本週
$sql = "WHERE created_at BETWEEN '{$range['start']}' AND '{$range['end']}'";
echo $sql;
?>

進階:DateTimeImmutable 版本 (PHP 5.5+,執行緒安全、鏈式操作)

modify('first day of this month')->format('Y-m-d 00:00:00');
    }
    return $dt->modify('last day of this month')->format('Y-m-d 23:59:59');
}

function getWeekRangeImmutable(string $date): array {
    $dt = new DateTimeImmutable($date);
    $dow = (int)$dt->format('N'); // 1=Mon..7=Sun
    $start = $dt->modify("-" . ($dow - 1) . " days")->setTime(0,0,0);
    $end = $dt->modify("+" . (7 - $dow) . " days")->setTime(23,59,59);
    return ['start' => $start->format('Y-m-d H:i:s'), 'end' => $end->format('Y-m-d H:i:s')];
}
?>

常見陷阱與最佳實務

陷阱解決
strtotime('last Monday') 行為模糊改用 DateTime 明確修飾詞:'this week Monday', 'last week Monday'
時區不一致統一設定 date_default_timezone_set('Asia/Taipei') 或在 DateTime 建構時指定
閏秒/夏令時間使用 DateTime 類別而非時間戳運算
週起始日定義不同明確文件:本文採 ISO-8601 (週一起),美國慣用週日起,溝通時對齊

結語

日期範圍計算看似簡單,卻藏著時區、週定義、閏年、夏令等坑。建議:

  1. **統一用 DateTimeImmutable** 取代 strtotime/date
  2. **封裝成工具類/服務**,全專案複用、單元測試覆蓋
  3. **資料庫查詢用 BETWEEN 閉區間**,注意秒級精度
  4. **前端傳遞 ISO 8601 字串** (2024-02-15T00:00:00+08:00),後端直接解析
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved