date()仅将时间戳转为字符串,不解析不计算;strtotime()是模糊猜测引擎,易因格式歧义出错;时区必须显式设置,复杂时间操作应改用DateTime类。

date() 和 strtotime() 不是“学会就能用”,而是得先明白它们各自管什么、在哪会翻车。
什么时候该用 date(),而不是 strtotime()
date() 只做一件事:把时间戳变成字符串。它不解析、不计算、不猜意图。
- 你要显示“2026-05-11 14:08:00”——直接
date('Y-m-d H:i:s') - 你要把数据库里存的
1715436480转成“今天下午2点”——date('n月j日 G:i', 1715436480) - 你传了个错的时间戳(比如
-1或0),date()仍会输出,但结果是 1970-01-01 或其他无效日期,不会报错 - 别用
date()去“判断今天是不是周一”——它没这个能力;要用date('w')提取星期几数字再比对
strtotime() 解析字符串为什么总出错
它不是解析器,是“猜测引擎”。遇到 '12/03/2025',PHP 可能按 m/d/Y 算成 2025 年 12 月 3 日,也可能按 d/m/Y 算成 3 月 12 日——取决于系统 locale 和 PHP 版本。
-
strtotime('2025-03-12')安全,因为Y-m-d是 ISO 标准,无歧义 -
strtotime('12-03-2025')危险,不同环境结果可能相反 -
strtotime('明天')在中文环境可能失败,官方文档明确说只支持英文关键词 - 真要处理用户输入的日期字符串,优先用
DateTime::createFromFormat('Y-m-d', $input),格式强制对齐,错就直接返回false
时区设置不是可选项,是必填项
不设时区,date() 和 strtotime() 都按服务器默认走。你的开发机在 UTC,测试服在 Asia/Shanghai,上线后时间差 8 小时——这种问题上线才暴露,改起来最疼。
- 第一行代码就该是
date_default_timezone_set('Asia/Shanghai')(或你业务实际需要的时区) -
date_default_timezone_get()返回空字符串?说明没设成功,别跳过检查 -
strtotime('today')返回的是“当前时区下的今天零点”,不是 UTC 的 00:00;如果存数据库用的是 UTC 时间,这里就得先转时区再算 - 用
DateTime类时,时区是对象级的,new DateTime('now', new DateTimeZone('UTC'))比全局设时区更可控
简单任务用函数,复杂逻辑必须切到 DateTime
加一天、减三小时、跨月计算、比较两个时间是否超过 48 小时——这些看似简单的事,用 strtotime('+1 day') 在月底或夏令时切换日大概率出错。
立即学习“PHP免费学习笔记(深入)”;
-
strtotime('+1 month')对 2026-01-31 执行,结果可能是 2026-02-28(不是 31 号),但没人告诉你为什么 -
$dt->modify('+1 month')行为一致,且可链式调用:$dt->modify('+1 month')->format('Y-m-d') - 要保留原始值?
$dt2 = clone $dt;,别指望strtotime()返回新值还能反向推原时间戳 - 涉及数据库存储,统一用 UTC 时间戳或
DateTime对象转 UTC 后存,避免本地时区污染
strtotime() 的模糊性、date() 的无状态性、时区的隐式依赖——这三块最容易在凌晨三点被报警叫醒。别等出问题才查,从第一个 date() 调用开始就带上时区,从第一个用户输入日期开始就用 createFromFormat()。



















