strtotime() 是 PHP 處理日期時間字符串的瑞士軍刀,能將「下周四」、「+1 month」等自然語言解析為 Unix 時間戳。本文系統講解核心用法、常見陷阱與最佳實踐。
strtotime("2009-1-22") // 1232553600 (當天 00:00:00)
strtotime("+1 day") // 明天這個時間
strtotime("-1 week") // 上周這個時間
strtotime("next Thursday") // 下周四 00:00:00
strtotime("last Monday") // 上周一 00:00:00
echo date('Y-m-d H:i:s', strtotime('+1 day'));
// 2024-01-23 14:30:00 (假設當前 2024-01-22 14:30:00)
| 表達式 | 含義 | 示例 |
|---|---|---|
+1 day / -1 day | 增減天 | strtotime('+2 days') |
+1 week / -2 weeks | 增減周 | strtotime('+1 week') |
+1 month / -3 months | 增減月(按日曆月) | strtotime('+1 month') |
+1 year | 增減年 | strtotime('+1 year') |
first day of / last day of | 本月首/末日 | strtotime('first day of next month') |
next/last <weekday> | 下/上一個周幾 | strtotime('next Friday') |
tomorrow / yesterday | 明天/昨天 | strtotime('tomorrow') |
now | 當前時間 | strtotime('now') === time() |
date('Y-m-d', strtotime('2024-01-31 +1 month')); // 2024-03-02 (非 02-31)
date('Y-m-d', strtotime('2024-01-31 +2 month')); // 2024-03-31
原因:PHP 先加月再修正天,2 月無 31 日自動滾動到 3 月。
對策:用 first day of +1 month 或 DateTime 類的 modify('first day of next month')。
strtotime() 使用 date_default_timezone_get() 返回的默認時區。跨時區部署必須統一設置:
date_default_timezone_set('Asia/Shanghai'); // 入口文件最早設置
// 或 php.ini: date.timezone = Asia/Shanghai
32 位整數最大值 2147483647 對應 2038-01-19 03:14:07 UTC。生產環境強制 64 位 PHP,或改用 DateTime 類(內部 64 位)。
strtotime('01/02/2024') // 美式 mm/dd/yyyy → 2024-01-02
strtotime('01-02-2024') // 歐式 dd-mm-yyyy → 2024-02-01
規範:只傳入 ISO 8601 格式 YYYY-MM-DD 或明確英文描述,避免數字分隔符歧義。
$dt = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
$dt->modify('+1 month')->modify('first day of this month');
echo $dt->format('Y-m-d H:i:s');
優勢:不可變對象(DateTimeImmutable)、鏈式調用、內建時區、無 2038 問題、格式化功能強大。
date_default_timezone_set()。DateTimeImmutable,僅在簡單腳本用 strtotime()。DATETIME,展示層按用戶時區轉換。駕馭時間,從理解 strtotime() 的規則與邊界開始。