date()函数第二参数必须为整数时间戳,传字符串会转为0导致输出1970-01-01;应先用strtotime()或DateTime解析字符串,推荐DateTime::createFromFormat()确保格式严格匹配并校验结果。

date() 函数不接受字符串参数,只处理时间戳
date() 的第一个参数是格式化字符串(如 'Y-m-d H:i:s'),第二个参数必须是整数类型的时间戳(秒级 Unix timestamp)。如果你传入字符串(比如 '2024-05-10' 或 'now'),PHP 会尝试把它转成整数——结果通常是 0,最终输出的是 Unix 元年(1970-01-01)的格式化结果。
常见错误现象:
– 传 date('Y-m-d', '2024-05-10') → 输出 1970-01-01
– 传 date('Y-m-d', 'tomorrow') → 同样是 1970-01-01(因为字符串转整数为 0)
- 正确做法:先用
strtotime()或DateTime把字符串解析成时间戳 - 推荐优先用
DateTime类,更可靠(尤其处理时区、非标准格式时) -
strtotime()对模糊表达(如'last Monday')支持好,但对格式不明确的字符串容易出错(如'05/10/2024'在不同地区可能被误判为月/日/年或日/月/年)
strtotime() 解析字符串失败的典型原因
strtotime() 不是万能解析器,它依赖启发式规则,对输入格式敏感。例如:
-
strtotime('2024-13-01')返回false(月份越界),但静默转为0,再喂给date()就又回到 1970 年 -
strtotime('10/05/2024')在 en-US 环境下被当作“10 月 5 日”,在 fr-FR 下可能被当作“10 日 5 月” - 含中文或全角字符(如
'2024年5月10日')基本无法识别,直接返回false
使用前务必检查返回值:if (($ts = strtotime($str)) === false) { /* 处理解析失败 */ }
立即学习“PHP免费学习笔记(深入)”;
安全可靠的字符串转日期方案(推荐 DateTime)
绕过 strtotime() 的歧义和边界问题,用 DateTime 显式指定格式:
$dt = DateTime::createFromFormat('Y-m-d', '2024-05-10');
if (!$dt || $dt->format('Y-m-d') !== '2024-05-10') {
// 解析失败或格式校验不通过(如 '2024-13-01' 会被创建但 format 结果异常)
}
echo $dt->format('Y年m月d日'); // 输出:2024年05月10日-
DateTime::createFromFormat()要求格式严格匹配,适合已知固定格式的输入(如表单提交的YYYY-MM-DD) - 若需兼容多种输入(如用户自由输入),可组合使用:
DateTime::createFromFormat()尝试已知格式 → 失败则 fallback 到new DateTime($str)(仍比裸用strtotime()更可控) - 注意时区:
new DateTime($str)默认用当前时区,DateTime::createFromFormat()不自动设时区,必要时调用setTimezone()
date() + 字符串传参的调试技巧
遇到结果不对,别急着改格式,先确认时间戳来源是否有效:
- 打印原始字符串:
var_dump($input_str);(检查空格、BOM、不可见字符) - 打印解析结果:
var_dump(strtotime($input_str));和var_dump(new DateTime($input_str)); - 开启错误报告:
error_reporting(E_ALL); ini_set('display_errors', '1');,DateTime构造失败会抛Exception,而strtotime()失败只返回false - 避免在生产环境依赖
date('Y-m-d', $unknown_string)这类写法——它掩盖了类型错误,且 PHP 8+ 会对非整数第二参数发出E_WARNING
真正难的不是格式化,而是确保你喂给 date() 的那个“时间”本身是准确、可信、有明确定义的。字符串到时间戳这一步,最容易被跳过验证,也最常埋雷。



















