首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP strtotime() 函數全攻略:相對時間、絕對時間與時區陷阱

     編輯:PHP 相關知識

strtotime() 是 PHP 處理日期時間字符串的瑞士軍刀,能將「下周四」、「+1 month」等自然語言解析為 Unix 時間戳。本文系統講解核心用法、常見陷阱與最佳實踐。

核心功能:英文時間描述 → 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

配合 date() 格式化輸出

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()

⚠️ 高發陷阱與避坑指南

1. 月份邊界「溢出」行為

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')。

2. 時區敏感性

strtotime() 使用 date_default_timezone_get() 返回的默認時區。跨時區部署必須統一設置:

date_default_timezone_set('Asia/Shanghai'); // 入口文件最早設置
// 或 php.ini: date.timezone = Asia/Shanghai

3. 32 位系統 2038 年問題

32 位整數最大值 2147483647 對應 2038-01-19 03:14:07 UTC。生產環境強制 64 位 PHP,或改用 DateTime 類(內部 64 位)。

4. 歧義格式

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 或明確英文描述,避免數字分隔符歧義。

現代替代方案:DateTime 不可變類

$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 問題、格式化功能強大。

最佳實踐清單

  1. 入口文件首行設置 date_default_timezone_set()。
  2. 業務代碼優先使用 DateTimeImmutable,僅在簡單腳本用 strtotime()。
  3. 存儲數據庫統一用 UTC 時間戳或 DATETIME,展示層按用戶時區轉換。
  4. 單元測試覆蓋月份邊界、閏年、DST 切換等邊界案例。

駕馭時間,從理解 strtotime() 的規則與邊界開始。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved