在實際開發中,經常需要根據當前日期計算本周、本月、上周、上月等時間範圍的起止時間,用於數據統計、報表查詢、定時任務等場景。本文提供一個功能完善、靈活可複用的 PHP 函數 getDateRange(),支持按天、周、月三種維度獲取任意偏移量的時間區間。
<?php
/**
* 獲取指定日期偏移量的時間範圍(開始時間、結束時間)
*
* @param string $date 基準日期,格式 'Y-m-d',默認今天
* @param string $type 類型:'d'=天, 'w'=周, 'm'=月
* @param int $offset 偏移量:0=本期, -1=上期, 1=下期
* @return array [start_datetime, end_datetime] 格式 'Y-m-d H:i:s'
*/
function getDateRange($date = '', $type = 'd', $offset = 0) {
// 默認基準日期為今天
$date = $date ?: date('Y-m-d');
$baseTime = strtotime($date);
switch ($type) {
case 'd': // 按天
$start = date('Y-m-d 00:00:00', strtotime("{$offset} day", $baseTime));
$end = date('Y-m-d 23:59:59', strtotime("{$offset} day", $baseTime));
break;
case 'w': // 按周(以周日為周末)
// 先計算基準日期所在周的周日
$sunday = strtotime('sunday', $baseTime);
// 根據偏移量調整周
$targetSunday = strtotime("{$offset} week", $sunday);
// 本周開始:周一(周日 -6 天)
$start = date('Y-m-d 00:00:00', strtotime('-6 days', $targetSunday));
// 本周結束:周日
$end = date('Y-m-d 23:59:59', $targetSunday);
break;
case 'm': // 按月
// 計算目標月份的第一天
$firstDay = strtotime("first day of {$offset} month", $baseTime);
$start = date('Y-m-01 00:00:00', $firstDay);
// 目標月份的最後一天 23:59:59
$end = date('Y-m-t 23:59:59', $firstDay);
break;
default:
throw new InvalidArgumentException("不支持的類型: {$type},請使用 d/w/m");
}
return [$start, $end];
}
?>
<?php
// 今天
list($todayStart, $todayEnd) = getDateRange('', 'd', 0);
// 昨天
list($yesterdayStart, $yesterdayEnd) = getDateRange('', 'd', -1);
// 本周(周一到周日)
list($weekStart, $weekEnd) = getDateRange('', 'w', 0);
// 上周
list($lastWeekStart, $lastWeekEnd) = getDateRange('', 'w', -1);
// 下周
list($nextWeekStart, $nextWeekEnd) = getDateRange('', 'w', 1);
// 本月
list($monthStart, $monthEnd) = getDateRange('', 'm', 0);
// 上月
list($lastMonthStart, $lastMonthEnd) = getDateRange('', 'm', -1);
// 下月
list($nextMonthStart, $nextMonthEnd) = getDateRange('', 'm', 1);
// 輸出測試
echo "今天: {$todayStart} ~ {$todayEnd}\n";
echo "本周: {$weekStart} ~ {$weekEnd}\n";
echo "本月: {$monthStart} ~ {$monthEnd}\n";
?>
'first day of +1 month'、'sunday'、'-6 days' 等,極大簡化了日期運算。-6 days 邏輯。date('Y-m-t') 直接獲取該月總天數,自動處理閏年、大小月。date_default_timezone_set('Asia/Shanghai'),避免跨時區項目出現偏差。DateRangeHelper,提供靜態方法調用。'q'(季度)、'y'(年)類型支持。DateTime 對象作為基準時間,提升面向對象代碼的兼容性。這個函數經過實際項目驗證,代碼簡潔、邏輯清晰,可直接集成到 Laravel、ThinkPHP、Symfony 等框架的公共工具庫中,或作為獨立 Helper 使用。