php默认时区非服务器本地时间,需显式调用date_default_timezone_set('asia/shanghai')设置,且必须在所有时间函数前执行;time()和$_server['request_time']返回utc时间戳,格式化时须绑定时区;mysql会话时区需单独设置,避免与php时区不同步;仅使用iana标准时区标识符如'asia/shanghai'。

PHP默认时区不是服务器本地时间
PHP启动时不会自动继承系统时区,date_default_timezone_get() 返回的是编译时设定的默认值(通常是 UTC 或空字符串),而非 /etc/timezone 或 date 命令显示的结果。这意味着即使服务器设为 Asia/Shanghai,PHP脚本仍可能按 UTC 解析时间。
- 用
date_default_timezone_set('Asia/Shanghai')显式设置,且必须在所有date()、strtotime()、DateTime初始化前调用 - 不推荐依赖
php.ini的date.timezone—— 容器或共享环境常被覆盖,运行时设置更可控 - 若用
DateTime构造时不传时区,它会使用当前默认时区;但new DateTime('2024-01-01')和new DateTime('2024-01-01', new DateTimeZone('UTC'))行为完全不同
$_SERVER['REQUEST_TIME'] 和 time() 不受时区设置影响
time() 和 $_SERVER['REQUEST_TIME'] 返回的是 Unix 时间戳(秒数),本质是 UTC 瞬间,与时区无关。它们不能直接格式化为本地时间,必须经 date() 或 DateTime 转换:
- 错误写法:
echo date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);—— 若未设默认时区,结果可能是 UTC 时间 - 正确写法:
date_default_timezone_set('Asia/Shanghai'); echo date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']); - 更安全写法:
(new DateTime())->setTimestamp($_SERVER['REQUEST_TIME'])->format('Y-m-d H:i:s'),显式绑定时区
MySQL连接与PHP时区不同步会导致时间存取错位
PHP时区和MySQL会话时区是两套独立系统。即使PHP设为 Asia/Shanghai,MySQL默认可能仍是 SYSTEM(即系统时区)或 UTC,造成 NOW()、FROM_UNIXTIME() 返回值与PHP预期不符。
- 连接后立即执行:
$pdo->exec("SET time_zone = '+08:00'");或"SET time_zone = 'Asia/Shanghai'" - 避免用
SELECT NOW()做时间基准 —— 改用SELECT UNIX_TIMESTAMP()获取时间戳再交由PHP格式化 - 存储时间字段建议统一用
INT UNSIGNED存时间戳,或用DATETIME配合明确时区转换逻辑,别依赖 MySQL 自动时区处理
DateTimeZone构造失败不报错但行为异常
new DateTimeZone('GMT+8') 或 new DateTimeZone('CST') 看似合理,实则无效 —— 这些不是 IANA 时区标识符,PHP会静默回退到 UTC,且不抛异常。
立即学习“PHP免费学习笔记(深入)”;
- 只使用标准 IANA 名称,如
'Asia/Shanghai'、'America/New_York';查列表用DateTimeZone::listIdentifiers() - 避免缩写:
'CST'在中国、美国、澳大利亚都存在歧义;'GMT+8'不支持夏令时切换 - 验证是否生效:
var_dump((new DateTime('now', new DateTimeZone('Asia/Shanghai')))->format('e, P'));输出应为Asia/Shanghai, +08:00











