在報表、統計、排程等業務中,常需動態計算「本週一至週日」、「上月 1 號至月末」、「本季度首尾日」等時間區間。PHP 提供 strtotime() 解析英文語意字串與 mktime() 組合時間戳兩大工具,善用它們能寫出可讀性高、不易出錯的日期邏輯。
語法:strtotime(string $datetime, int $baseTime = time()) : int|false
支援相對格式:+1 day、next Monday、first day of this month、last day of -1 month 等。
// 今天
echo date('Y-m-d', strtotime('today'));
// 本週一(週一為週首)
echo date('Y-m-d', strtotime('monday this week'));
// 本週日
echo date('Y-m-d', strtotime('sunday this week'));
// 上週一
echo date('Y-m-d', strtotime('monday last week'));
// 本月第一天
echo date('Y-m-d', strtotime('first day of this month'));
// 本月最後一天
echo date('Y-m-d', strtotime('last day of this month'));
// 上月第一天
echo date('Y-m-d', strtotime('first day of last month'));
// 上月最後一天
echo date('Y-m-d', strtotime('last day of last month'));
// 本季度第一天
echo date('Y-m-d', strtotime('first day of this quarter'));
// 本季度最後一天
echo date('Y-m-d', strtotime('last day of this quarter'));
語法:mktime(int $hour, int $minute, int $second, int $month, int $day, int $year) : int
參數從右至左可省略,預設為當前 GMT 時間對應值。適合需要「精確到秒」的區間邊界(如 00:00:00 ~ 23:59:59)。
function rangeThisWeek(): array {
$monday = strtotime('monday this week');
$sunday = strtotime('sunday this week 23:59:59');
return [$monday, $sunday];
}
function rangeLastWeek(): array {
$monday = strtotime('monday last week');
$sunday = strtotime('sunday last week 23:59:59');
return [$monday, $sunday];
}
function rangeThisMonth(): array {
$first = strtotime('first day of this month');
$last = strtotime('last day of this month 23:59:59');
return [$first, $last];
}
function rangeLastMonth(): array {
$first = strtotime('first day of last month');
$last = strtotime('last day of last month 23:59:59');
return [$first, $last];
}
function rangeThisQuarter(): array {
$first = strtotime('first day of this quarter');
$last = strtotime('last day of this quarter 23:59:59');
return [$first, $last];
}
// 使用範例
[$start, $end] = rangeThisMonth();
$sql = "SELECT * FROM orders WHERE created_at BETWEEN '$start' AND '$end'";
date_default_timezone_set('Asia/Taipei'),避免跨日邊界計算錯誤。strtotime('last day of this month') 自動處理 28/29/30/31 日,比手算 date('t') 更直觀。strtotime('monday this week') 遵循 ISO,若需週日為首請用 sunday this week。DateTimeImmutable 鏈式操作,型別安全且避免副作用:(new DateTimeImmutable('monday this week'))->format('Y-m-d')| 場景 | 推薦函式 | 理由 |
|---|---|---|
| 相對日期語意(下週一、上月首日) | strtotime | 程式碼可讀性極高,自動處理月份天數差異 |
| 固定格式組裝(如 00:00:00) | mktime | 參數明確,避免字串解析歧義 |
| 大量日期運算、需型別提示 | DateTimeImmutable | 現代 OO 風格,不可變、可測試、IDE 友善 |
掌握 strtotime 的相對語法與 mktime 的精確組裝,配合統一時區設定,即能輕鬆應對各類報表區間需求。新專案建議直接採用 DateTimeImmutable 享受現代 PHP 的型別優勢。