strtotime() 解析失败主因是时区未显式设置及字符串格式不标准,应优先用 datetime 类配合时区对象或 createfromformat() 指定格式,并避免在循环中重复调用。

strtotime() 解析失败时先看时区设置
PHP 的 strtotime() 默认按当前时区解析字符串,但很多日期字符串(比如 "2023-10-05" 或 "Oct 5, 2023")本身不带时区信息,strtotime() 就会套用 date_default_timezone_get() 返回的时区——这常导致时间戳比预期快/慢 8 小时(如服务器在 UTC,而你想要北京时间)。
- 运行前务必显式设置时区:
date_default_timezone_set('Asia/Shanghai'); - 如果不能改全局时区,就用
DateTime类配合时区对象:new DateTime('2023-10-05', new DateTimeZone('Asia/Shanghai')); - 避免依赖系统默认时区,Docker 容器或共享主机上很可能返回
UTC或报Warning: strtotime(): It is not safe to rely on the system's timezone settings
含中文或非标准格式的字符串别硬塞给 strtotime()
strtotime() 对中文(如 "2023年10月5日")、全角符号、空格不一致、甚至带多余换行的字符串基本无能为力,直接返回 false,转成 0(即 1970-01-01)。
- 先用
str_replace()或正则清理:把年/月/日换成-,去掉全角空格和制表符 - 更稳妥的是用
DateTime::createFromFormat(),它支持自定义格式:DateTime::createFromFormat('Y年m月d日', '2023年10月5日') - 注意:该方法失败时返回
false,且不会抛异常,必须手动检查:if (!$dt) { throw new InvalidArgumentException('日期格式错误'); }
ISO 8601 和 RFC 2822 字符串优先走 DateTime 构造函数
像 "2023-10-05T14:30:00+0800"、"Thu, 05 Oct 2023 14:30:00 +0800" 这类标准格式,DateTime 构造函数原生支持,比 strtotime() 更准、更可控。
- 直接传入即可:
$dt = new DateTime('2023-10-05T14:30:00+0800'); - 它自动识别时区偏移,
$dt->getTimestamp()得到的就是对应 UTC 时间戳 - 而
strtotime('2023-10-05T14:30:00+0800')在旧 PHP 版本(如 5.2)可能忽略时区,结果错八小时 - 若需兼容 PHP 5.2+,可用
DateTime::createFromFormat('c', $str)替代构造函数
性能敏感场景下避免反复调用 strtotime()
在循环里对同一字符串反复调用 strtotime() 是常见低效写法——它内部要做大量正则匹配和语义推断,比 DateTime::createFromFormat() 慢 2–3 倍(实测百万次调用差异明显)。
立即学习“PHP免费学习笔记(深入)”;
- 固定格式字符串(如
"Y-m-d H:i:s")一律用DateTime::createFromFormat() - 若格式不确定但来源可信(如数据库字段),可缓存解析结果,或提前统一归一化为 ISO 格式再处理
- 注意:
DateTime::createFromFormat()的格式字符串中,Y表示 4 位年份,y是 2 位;H是 24 小时制,h是 12 小时制——错一个字母就返回 false











