strtotime() 是 PHP **最強大、最常用**的時間字串解析函數,支援**英文自然語言相對時間**、多種標準格式、時區處理。本文詳細說明語法、支援格式、相對時間語法、時區陷阱、回傳值規則、效能優化與實戰範例 (工作日計算、下 N 週列表、驗證解析失敗)。
strtotime(string $datetime, int $baseTimestamp = time()): int|false
false (PHP 5.1+),**舊版回傳 -1**。$baseTimestamp 作為相對時間的基準點 (預設 time())。| 類別 | 範例 | 說明 |
|---|---|---|
| 標準日期 | 2024-01-15, 15 Jan 2024, January 15, 2024 | ISO 8601、美式、英式 |
| 時間 | 14:30:59, 2:30pm | 24/12 小時制 |
| 相對時間 (核心威力) | +1 day, next Thursday, last Monday, first day of next month | 關鍵字 + 數量 + 單位 |
| 複合相對 | +1 week 2 days 4 hours 2 seconds | 空白分隔多段 |
| 關鍵字 | now, today, tomorrow, yesterday | 當下/今日/明日/昨日 |
單位: second/minute/hour/day/week/month/year (可複數 s)
方向: + / - / 空白 (預設 +)
特殊: next / last / this / first / second / third / fourth / fifth
月份邊界: first day of / last day of / midday / midnight
週邊界: monday / tuesday ... sunday (next/last 修飾)
function nextWeeksDay(int $base, int $weeks): array {
$result = [];
for ($i = 1; $i <= $weeks; $i++) {
$result[$i] = date('D d M Y', strtotime("+$i week", $base));
}
return $result;
}
$base = strtotime('2024-01-15');
print_r(nextWeeksDay($base, 52));
$str = 'Not a date';
$ts = strtotime($str);
if ($ts === false) {
echo "無法解析: $str";
} else {
echo date('Y-m-d H:i:s', $ts);
}
function workingDays(int $year): int {
$holidays = [
1 => [1], // 元旦
2 => [10,11], // 春節範例
5 => [1], // 勞動節
10 => [10], // 國慶
// ... 自訂
];
$start = strtotime("$year-01-01");
$end = strtotime("$year-12-31");
$count = 0;
for ($ts = $start; $ts <= $end; $ts = strtotime('+1 day', $ts)) {
$dow = (int)date('N', $ts); // 1=Mon .. 7=Sun
if ($dow < 6 && !in_array((int)date('j', $ts), $holidays[(int)date('n', $ts)] ?? [])) {
$count++;
}
}
return $count;
}
echo workingDays(2024);
$first = strtotime('first day of this month');
$last = strtotime('last day of this month 23:59:59');
| 陷阱 | 說明 | 解決 |
|---|---|---|
| 預設時區 | 若未設 date.timezone,PHP 會猜測並發 E_WARNING | date_default_timezone_set('Asia/Taipei') 或 php.ini 設定 |
| 夏令時間 (DST) | 相對 +1 day 在 DST 切換日可能為 23/25 小時 | 使用 DateTime + DateInterval 進行日曆運算 |
| 基準時間傳遞 | strtotime('+1 day', $ts) 以 $ts 所在時區計算 | 確保 $ts 來源時區一致 |
| 微秒支援 | PHP 5.0+ 允許微秒字串,但 **strtotime 忽略微秒** | 需微秒精度用 DateTime::createFromFormat('U.u', ...) |
| 場景 | 推薦 | 理由 |
|---|---|---|
| 簡單字串→Timestamp、相對時間快速計算 | strtotime | 單行代碼、效能極佳、語法直覺 |
| 複雜時區轉換、DST 安全運算、不可變物件 | DateTime | 物件導向、時區感知、支援微秒、格式化靈活 |
| 固定格式解析 (如 log 日期) | DateTime::createFromFormat | 嚴格格式、效能優於 strtotime 正則解析 |
| 國際化日期輸入 | IntlDateFormatter | 支援當地語系格式 |
strtotime('+1 day'):~45msnew DateTime('+1 day'):~120msDateTime::createFromFormat('Y-m-d', $date):~80ms高頻呼叫 (如迴圈內) **優先用 strtotime**;物件導向架構統一用 DateTime。
if ($ts) 判斷:strtotime('1970-01-01') 回傳 0 (false-y),**必須用 === false** 判斷失敗。strtotime('2024-01-31 +1 month') → 2024-03-02 (PHP 修正為月底);需精確用 DateTime。next Monday 在週一當天指**下週一**,非今天;this Monday 才指本週一。掌握 strtotime() 豐富語法與時區邊界,能以**最少代碼**解決 90% 日期時間業務需求;複雜場景無縫切換 DateTime 物件模型,構建健壯時間處理層。