PHP获取当前时间戳应直接使用time(),它轻量、可靠、不依赖时区;避免strtotime('now')等冗余解析,注意时区统一设置与跨系统时间戳比对陷阱。

PHP里获取当前时间戳用 time(),别用 strtotime('now')
直接调用 time() 是最轻量、最可靠的方式。它不依赖时区设置,返回整数秒级时间戳,底层调用系统 gettimeofday(),几乎没有开销。
常见错误是写 strtotime('now') 或 strtotime(date('Y-m-d H:i:s')) —— 这多绕两道:先格式化再解析,既慢又可能因时区/语言环境出错(比如服务器 locale 设为中文时,strtotime('今天') 可能意外生效)。
-
time()返回的是 Unix 时间戳(从 1970-01-01 00:00:00 UTC 起的秒数),和服务器时区无关 - 如果需要带毫秒的时间戳,得自己组合:
round(microtime(true) * 1000),但注意microtime(true)是浮点数,有精度风险 - 在 CLI 模式下,
time()和date('U')结果一致;但在 Web SAPI(如 Apache/FPM)中,若脚本执行时间长,date('U')可能因内部缓存略滞后于time()
用 date() 格式化时间戳时,date_default_timezone_set() 必须提前设好
PHP 默认时区是 UTC,但多数项目需要本地时间(如东八区)。不显式设置时区,date() 输出会错,且 PHP 8.1+ 会在错误报告中抛 Warning: date(): It is not safe to rely on the system's timezone settings。
别在每个 date() 前手动传时区参数(比如 date('Y-m-d', $ts, new DateTimeZone('Asia/Shanghai'))),太重,也容易漏。
立即学习“PHP免费学习笔记(深入)”;
- 统一在入口文件(如
index.php或配置引导文件)开头加date_default_timezone_set('Asia/Shanghai') - 避免用
date_default_timezone_set('PRC')—— 这个缩写已被弃用,PHP 8.0+ 不再识别 - 如果项目需支持多时区(如用户自选时区),应把时间戳存为 UTC,在展示层用
DateTime+setTimezone()转换,而不是反复调用date()
strtotime() 解析字符串要小心模糊输入和跨月逻辑
strtotime() 看似方便,但对自然语言输入极其敏感。比如 strtotime('last day of next month') 在 1 月 31 日运行,可能返回 3 月 3 日而非 2 月 28 日——因为“next month”先算到 2 月,再找“last day”,而 2 月没有 31 日,自动溢出到 3 月。
它适合快速原型或日志分析这类容错场景,不适合金融、定时任务等强确定性需求。
- 绝对避免用
strtotime('tomorrow')做定时任务基准——它依赖当前时间,若脚本凌晨 23:59 执行,可能跳到后天 - 想取“本月第一天”,用
strtotime('first day of this month')比strtotime('Y-m-01')安全,后者在m=2时硬写01会失效 - 解析用户输入的日期字符串前,先用
DateTime::createFromFormat()尝试严格格式匹配(如Y-m-d),失败再 fallback 到strtotime(),防止注入式歧义(如"+1 day 2020-01-01")
时间戳比较别直接用 ==,注意时区与精度陷阱
两个时间戳变量看似相等,但可能是不同来源(time() vs filemtime() vs MySQL UNIX_TIMESTAMP()),隐含精度或时区偏差。尤其在数据库交互中,MySQL 的 UNIX_TIMESTAMP(NOW()) 返回的是服务器时区下的时间戳,若 MySQL 时区设为 +00:00 而 PHP 设为 Asia/Shanghai,直接比对会差 8 小时。
- 跨系统比时间戳前,确认双方都基于 UTC:MySQL 中设
SET time_zone = '+00:00',PHP 中确保date_default_timezone_set('UTC') - 涉及秒级以下精度(如微秒日志对齐),别用
time(),改用hrtime(true)(PHP 7.3+),它返回纳秒整数,无浮点误差 - 判断“是否超过 5 分钟”,别写
$now - $old > 300,而应写$now >= $old + 300——防止极端情况下$now回拨(NTP 同步、虚拟机暂停)导致负值误判
事情说清了就结束。时间戳看着简单,但混着时区、精度、系统差异一起用,最容易在上线后半夜三点爆出来。











