給定起始月份與結束月份 (格式 Y-m),回傳包含該區間內每個月份字串的陣列。支援參數為空時自動預設為「上個月」到「本月」。
<?php
/**
* 取得月份區間陣列
* @param string|null $start 起始月份 'Y-m',預設為上個月
* @param string|null $end 結束月份 'Y-m',預設為本月
* @return array 格式 ['2024-01', '2024-02', ...]
*/
function getMonthRange($start = null, $end = null) {
// 1. 參數預設值
$start = $start ?: date('Y-m', strtotime('-1 month'));
$end = $end ?: date('Y-m');
// 2. 轉換為該月 1 號 00:00:00 的時間戳
$startTs = strtotime($start . '-01');
$endTs = strtotime($end . '-01');
if ($startTs > $endTs) {
// 起始晚於結束,交換或回傳空陣列
return [];
}
// 3. 迴圈產生月份
$months = [];
$current = $startTs;
while ($current <= $endTs) {
$months[] = date('Y-m', $current);
// 增加一個月:strtotime('+1 month', $current) 會自動處理跨年、月末天數差異
$current = strtotime('+1 month', $current);
}
return $months;
}
?>
<?php
// 1. 完整指定
print_r(getMonthRange('2023-01', '2023-06'));
/*
Array
(
[0] => 2023-01
[1] => 2023-02
[2] => 2023-03
[3] => 2023-04
[4] => 2023-05
[5] => 2023-06
)
*/
// 2. 僅給起始,結束預設為本月
print_r(getMonthRange('2024-01'));
// 輸出 2024-01 到當前月份
// 3. 參數皆為空:預設上個月 ~ 本月
print_r(getMonthRange());
// 例:今天 2024-05-20 -> ['2024-04', '2024-05']
?>
strtotime('Y-m-01') 消除每月天數不同造成的計算誤差。strtotime('+1 month', $ts):PHP 內建日期運算自動處理 1/31 → 2/28(29)、12/31 → 1/31 等邊界情況,比手動加秒數 (86400*天數) 可靠得多。$current <= $endTs 確保包含結束月份。LEFT JOIN 或陣列合併,確保無資料月份顯示 0 而非缺失。categories 資料來源。<?php
function getMonthRangeEx($start = null, $end = null, $format = 'Y-m') {
$months = getMonthRange($start, $end);
return array_map(fn($m) => date($format, strtotime($m . '-01')), $months);
}
// 用法
getMonthRangeEx('2023-01', '2023-03', 'Y年m月'); // ['2023年01月', '2023年02月', '2023年03月']
?>