date() 函数传入 false 或 null 会触发警告,应先校验时间戳是否为大于0的整数;推荐用 datetime::createfromformat() 替代 strtotime() 处理不确定格式;务必设置默认时区并统一使用 utc 存储时间戳。

date() 函数传入 false 或 null 会直接警告
PHP 的 date() 不接受无效时间戳,比如从数据库查出的空值、null、false 或字符串 "0000-00-00" 转成时间戳后是 false。这时调用 date('Y-m-d', $ts) 会触发 Warning: date(): Invalid date format。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 永远先判断时间戳是否为整数且大于 0:
is_int($ts) && $ts > 0 - 更稳妥的做法是用
strtotime()后立刻检查:$ts = strtotime($input); if ($ts === false) { $ts = time(); } - 数据库字段为
DATE或DATETIME时,用COALESCE(created_at, NOW())在 SQL 层兜底,避免 PHP 层处理空值
strtotime() 解析模糊字符串可能返回意外结果
strtotime() 对非标准格式容忍度高,但容易误判。比如 "2023-02-30" 会被自动转成 2023-03-02(而非报错),"31/2/2023" 直接返回 false,而 "2023/13/01" 又可能变成 2024-01-01。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 只对已知格式的字符串用
strtotime();不确定来源时,优先用DateTime::createFromFormat() - 例如严格匹配
Y-m-d:$dt = DateTime::createFromFormat('Y-m-d', $str); if (!$dt || $dt->format('Y-m-d') !== $str) { /* 格式错误 */ } - 注意
DateTime::createFromFormat()第二个参数为false时返回false,不是异常,必须手动判断
时区未设置导致 date() 输出和预期不一致
PHP 默认时区是 UTC,但服务器配置、php.ini、或脚本中没设时区时,date() 和 strtotime() 都按 UTC 解析/输出,容易在本地测试正常、上线后出错。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 在入口文件(如
index.php)开头加date_default_timezone_set('Asia/Shanghai');,不要依赖 php.ini - 避免混用时区:
date()受默认时区影响,DateTime实例默认用系统时区,但可显式指定:new DateTime('now', new DateTimeZone('Asia/Shanghai')) - 存储时间戳统一用 UTC,展示前再转本地时区,避免在数据库里存带时区的字符串
MySQL 时间函数和 PHP date() 行为不一致
比如 MySQL 的 NOW() 返回的是服务器当前时间(含时区),而 PHP 的 date('Y-m-d H:i:s') 是 PHP 进程所在时区的时间。如果 MySQL 和 PHP 时区不同,直接拼 SQL 插入 date('Y-m-d H:i:s') 可能跨天或偏移一小时。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- PHP 写入时间字段时,优先用
UNIX_TIMESTAMP()或UTC_TIMESTAMP(),而不是拼字符串 - 如果必须用 PHP 拼时间字符串,确保 MySQL 也设为同一时区:
SET time_zone = '+08:00'; - 读取时间字段时,别用
date('Y-m-d', strtotime($row['created_at']))—— 字符串转时间戳再转回字符串,精度和时区都可能丢失;直接用DateTime解析:new DateTime($row['created_at'])
最常被忽略的是:日期逻辑一旦涉及跨日、夏令时、或用户时区切换,仅靠 date() 和 strtotime() 很难兜住边界情况,DateTime 类才是可控的起点。











