真正难的不是记住函数名,而是每次拿到时间值都需确认时区、精度及下游解释方式;time() 返回UTC秒级时间戳需用date()格式化查看,strtotime()易因格式模糊出错,DateTime类才能安全处理时区、夏令时与边界日期。

time() 是最直接的起点,但只靠它写不出健壮的时间逻辑——真正卡住人的从来不是“怎么取时间”,而是“取完之后怎么不出错”。
用 time() 获取当前时间戳,但别直接拿去显示
它返回的是整数秒级时间戳,比如 1715478480,这数字对人毫无意义。常见错误是直接 echo time(); 然后以为“时间拿到了”,结果日志里全是数字,调试时还得反查。
- 正确做法:立刻配一个
date('Y-m-d H:i:s', time())对照看,确认时区和值是否合理 - 注意:
time()不受date_default_timezone_set()影响(它本来就是 UTC 秒数),但后续date()会受其影响 - 服务器时区没设?
date_default_timezone_get()很可能返回UTC或空字符串,导致date()输出错乱
strtotime() 解析字符串很爽,但容易在模糊格式上翻车
它能认 "next Monday"、"-2 hours",但遇到 "05/06/2025" 这种写法,PHP 会按 m/d/Y 解(美国习惯),而中国开发者常以为是 d/m/Y —— 结果解析成 6月5日还是5月6日,全看运气。
- 安全替代:用
DateTime::createFromFormat('Y-m-d', '2025-05-06')显式指定格式 -
strtotime()返回false时不报错,必须手动判断:if (false === $ts) { /* 处理失败 */ } - 别传空字符串或 null 给它,PHP 7+ 会警告,PHP 8+ 直接 TypeError
用 DateTime 类做计算,别用 time() 加减硬算
比如“30天后过期”,写成 time() + 30 * 86400 看似简单,但忽略夏令时切换、闰秒、甚至2月天数不一致——2月30号根本不存在,这种算法会在边界日期崩。
立即学习“PHP免费学习笔记(深入)”;
- 正确姿势:
$dt = new DateTime(); $dt->modify('+30 days');或$dt->add(new DateInterval('P30D')); - 需要不可变对象?用
DateTimeImmutable,避免意外修改原对象 - 跨时区比较?先统一转成 UTC:
$dt->setTimezone(new DateTimeZone('UTC'));,再取getTimestamp()
存数据库和传前端时,时间戳类型选错会埋坑
MySQL 的 TIMESTAMP 和 DATETIME 行为完全不同:TIMESTAMP 自动转为 UTC 存储、读取时转回会话时区;DATETIME 则原样存原样读。如果 PHP 写入前没处理好时区,查出来的时间就可能偏 8 小时。
- 推荐方案:PHP 全局设
date_default_timezone_set('UTC'),所有时间以 UTC 存DATETIME,展示时再转本地时区 - API 返回 JSON?别直接
json_encode(['time' => time()]),前端 JS 的new Date(1715478480 * 1000)是对的,但要注明单位是秒 - Redis 缓存过期时间?它只认秒级整数,
microtime(true)得floor()后再用
真正难的不是记住函数名,而是每次拿到一个时间值,下意识问自己三句话:它基于什么时区?精度够不够用?下游系统怎么解释它?



















