PHP中date_default_timezone_set()不支持"GMT"或"UTC"作为有效时区标识符,必须使用IANA地理时区(如Europe/London)或Etc/UTC;设为"UTC"虽可运行但无夏令时支持且date('e')为空,"GMT"在PHP 8.0+会报错。

UTC 和 GMT 在 PHP 时区设置中几乎可以互换使用,但它们本质不同:GMT 是基于天文观测的本地时间标准(英国格林尼治平太阳时),而 UTC 是基于原子钟的国际协调时间,会通过闰秒调整以逼近 GMT。PHP 的 date_default_timezone_set() 内部全部依赖 IANA 时区数据库(如 Europe/London),**不接受直接传入 "GMT" 或 "UTC" 作为时区标识符**——这是最常踩的坑。
PHP 中 date_default_timezone_set() 不支持 "GMT" 和 "UTC" 字符串
虽然文档里写着“支持 ‘UTC’”,但实际行为是:PHP 会把 "UTC" 当作一个“伪时区”处理,它不参与夏令时计算、不带偏移历史、也不触发 IANA 数据库校验。这意味着:
-
date_default_timezone_set("UTC")可运行,但返回的date('e')是空字符串,date('T')固定为"UTC",无法反映真实地理时区行为 -
date_default_timezone_set("GMT")在 PHP 8.0+ 会抛出Warning: date_default_timezone_set(): Unknown or bad timezone (GMT) - 用
"UTC"设置后,strtotime("12:00 Europe/London")这类跨时区解析可能出错,因为 PHP 缺少上下文映射
正确做法:优先使用 IANA 地理时区标识符
IANA 时区(如 Asia/Shanghai、America/New_York)包含完整的历史偏移与夏令时规则,PHP 能据此做准确转换。即使你需要“无偏移”的逻辑,也应选 UTC 对应的地理等效项:
- 需要稳定 +00:00 且不随夏令时变动 → 用
Etc/UTC(注意:Etc/GMT实际表示 +00:00,但Etc/GMT+0表示 -00:00,符号是反的) - 服务面向英国用户且需尊重夏令时 → 用
Europe/London(冬令时 GMT,夏令时 BST = GMT+1) - 日志统一存 UTC 时间 → 直接设
date_default_timezone_set("Etc/UTC"),再用date('c')输出 ISO 8601 时间
date_default_timezone_get() 返回值不代表当前系统时区真实状态
这个函数只返回上次 date_default_timezone_set() 设的值,或 php.ini 中 date.timezone 的配置值。它不会检测系统时钟是否真的同步、是否被修改过。常见误判场景:
立即学习“PHP免费学习笔记(深入)”;
- php.ini 中设了
date.timezone = "Asia/Shanghai",但服务器系统时区是/etc/localtime → America/Chicago→ PHP 时间函数仍按上海算,和系统日志时间对不上 - CLI 和 FPM SAPI 的配置可能不同:CLI 下
date_default_timezone_get()返回"UTC",但 Apache mod_php 下返回"Europe/Berlin" - 用
ini_set("date.timezone", "UTC")临时修改,仅对当前请求生效,不影响其他并发请求
真正影响时间输出的是时区标识符背后绑定的 IANA 数据版本 —— 不同 PHP 版本内置的 tzdata 年份不同,比如 PHP 7.4 默认含 2019a 数据,而 PHP 8.2 含 2023c。如果你依赖某个国家新增的夏令时规则,光改字符串没用,得升级 PHP 或手动更新 tzdata。











