初學者常遇到 date('Y-m-d H:i:s') 輸出時間比本地時間少 8 小時(UTC 與 CST 差值)。根因:PHP 5.1+ 引入 date.timezone 配置,默認未設置時引擎按 UTC 計算。本文提供三種修正方案與生產環境最佳實踐。
一、現象復現
<?php
echo date('Y-m-d H:i:s'); // 2024-01-15 02:30:00 (UTC)
// 實際北京時間 2024-01-15 10:30:00
二、三種修正方案
方案 1:修改 php.ini(全局生效,需重啟 PHP-FPM/Apache)
; 找到 [Date] 區塊
date.timezone = "Asia/Shanghai"
; 或 PRC、Asia/Chongqing、Asia/Urumqi 等
優點:一次配置全項目生效。缺點:無權限修改共享主機/容器時無法使用。
方案 2:腳本入口調用 date_default_timezone_set()(推薦,可移植)
<?php
// 公共引導文件 bootstrap.php / config/app.php
date_default_timezone_set('Asia/Shanghai');
// 或動態讀取配置
date_default_timezone_set(config('app.timezone', 'Asia/Shanghai'));
優點:代碼級控制、版本庫可追蹤、無需服務器權限。缺點:需確保所有入口(CLI、Queue Worker、Cron)均包含該文件。
方案 3:運行時 ini_set()(不推薦)
ini_set('date.timezone', 'Asia/Shanghai'); // 部分系統函數可能不生效
三、常用中國時區標識符對照表
| 標識符 | 適用地區 | 備註 |
| Asia/Shanghai | 上海/北京/大陸標準時間 | 推薦首選 |
| PRC | 中華人民共和國 | 別名,等同 Asia/Shanghai |
| Asia/Chongqing | 重慶 | |
| Asia/Urumqi | 烏魯木齊 | 實際同一時區 |
| Asia/Harbin | 哈爾濱 | |
| Asia/Hong_Kong | 香港 | |
| Asia/Macao | 澳門 | |
| Asia/Taipei | 台北 | |
| Asia/Singapore | 新加坡 | 同 UTC+8 |
四、進階:DateTime 物件導向用法(PHP 5.2+)
$dt = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
echo $dt->format('Y-m-d H:i:s'); // 10:30:00
// 修改時區不改變時間點
$dt->setTimezone(new DateTimeZone('UTC'));
echo $dt->format('Y-m-d H:i:s'); // 02:30:00
// 互操作:獲取時間戳
echo $dt->getTimestamp(); // 1705285800
五、Docker / Kubernetes 環境最佳實踐
- 鏡像構建時設置:
ENV TZ=Asia/Shanghai + RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
php.ini 掛載配置:date.timezone = ${PHP_TIMEZONE:-Asia/Shanghai}
- 容器啟動腳本兜底:
date_default_timezone_set(getenv('PHP_TIMEZONE') ?: 'Asia/Shanghai');
六、常見坑點避雷
- strtotime() 解析無時區字符串:
strtotime('2024-01-15 10:00') 會按 date.timezone 解析,跨時區傳輸請帶時區 2024-01-15 10:00+08:00 或用 DateTime。
- MySQL TIMESTAMP vs DATETIME:TIMESTAMP 存儲 UTC,讀取按會話時區轉換;DATETIME 不轉換。PHP 端時區必須與 DB 會話時區一致(
SET time_zone = '+08:00')。
- 日誌/監控系統:統一用 UTC 存儲,展示層按用戶偏好轉換。
結論:在項目啟動階段統一調用 date_default_timezone_set('Asia/Shanghai') 是最穩健、可移植的方案,配合容器環境變量注入,徹底解決 8 小時時差問題。
- 上一篇文章: PHP Session 深度解析:是否必須依賴 Cookie?無 Cookie 環境下的 Session 傳遞機制與跨窗口實踐
- 下一篇文章: PHP 4/5 構造函數兼容寫法:雙構造函數模式與 __construct 優先級詳解
Copyright ©
程式碼之家 All Rights Reserved