date() 格式化本地時間,gmdate() 格式化 GMT/UTC 時間。兩者在不同時區、作業系統、SAPI 下行為可能不一致。本文深入解析差異根因,提供跨平台統一時區的最佳配置方案。
<?php
// 假設伺服器系統時區為 UTC,PHP 預設時區亦為 UTC
// 當前 UTC 時間:2024-01-15 04:15:27
echo date('Y-m-d H:i:s'); // 2024-01-15 04:15:27(本地時間 = UTC)
echo gmdate('Y-m-d H:i:s'); // 2024-01-15 04:15:27(GMT 時間)
// 若 php.ini 設定 date.timezone = Asia/Shanghai (UTC+8)
// 同一時間點:
echo date('Y-m-d H:i:s'); // 2024-01-15 12:15:27(北京時間)
echo gmdate('Y-m-d H:i:s'); // 2024-01-15 04:15:27(仍為 GMT)
PHP 5.3 前,Windows 版 PHP date() 內部強制以 UTC 計算,導致未設定時區時 date() 與 gmdate() 輸出相同。Linux 下則遵循系統時區。現代 PHP(5.4+)已統一行為:均以 date.timezone 或 date_default_timezone_set() 為準。
; php.ini date.timezone = "Asia/Shanghai" ; 或 "PRC"、"Asia/Chongqing"、"Etc/GMT-8"
重啟 PHP-FPM/Apache 生效。所有腳本自動使用北京時間,date() 輸出本地時間,gmdate() 仍輸出 UTC。
<?php
// 所有輸出時間前調用,建議放在公共引入文件
date_default_timezone_set('PRC'); // 中華人民共和國,等同 Asia/Shanghai
echo date('Y-m-d H:i:s'); // 北京時間
TIMESTAMP/DATETIME 統一存儲 UTC(time() 返回 UTC 時間戳)。timezone 欄位(如 Asia/Shanghai、America/New_York)。new DateTime('@' . $timestamp, new DateTimeZone('UTC'))->setTimezone(new DateTimeZone($userTz))->format('Y-m-d H:i:s')。優勢:全球用戶見到各自本地時間,資料層零時區耦合,夏令時自動處理。
| 地區 | 標識符 | UTC 偏移 |
|---|---|---|
| 中國大陸/香港/台灣 | Asia/Shanghai, PRC, Asia/Hong_Kong, Asia/Taipei | +08:00 |
| 新加坡/馬來西亞 | Asia/Singapore, Asia/Kuala_Lumpur | +08:00 |
| 日本/韓國 | Asia/Tokyo, Asia/Seoul | +09:00 |
| 美國東部 | America/New_York | -05:00/-04:00 (DST) |
| 歐洲中部 | Europe/Berlin, Europe/Paris | +01:00/+02:00 (DST) |
| UTC | UTC, GMT | +00:00 |
time() + 3600*8 硬編碼偏移,無法處理夏令時、時區變更。DateTime 物件導向 API 比 date()/gmdate() 更強大、可讀、安全,新專案優先使用。ENV TZ=Asia/Shanghai 或 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime。