strtotime()相减可得秒数,但需检查返回值是否为整数以防解析失败;含毫秒、跨时区或夏令时场景应优先使用datetime对象显式处理。

直接用 strtotime() 相减就能得到秒数,但必须确保两个时间都成功解析
PHP 里最常用、也最直觉的方式就是把两个时间字符串转成时间戳再相减:strtotime($end) - strtotime($start)。结果单位就是秒,不需要额外换算。
关键点在于:strtotime() 遇到无法识别的时间格式会返回 false,而 false 在算术运算中会被转成 0,导致结果变成负数或零——这很容易被当成“时间差很小”,实际是解析失败了。
- 务必检查返回值是否为整数:
is_int(strtotime($time)) - 常见失败格式:
"2024-02-30"(不存在的日期)、"2024/13/01"(月份越界)、"下午3点"(中文表述不被默认支持) - 推荐先用
date_default_timezone_set()设好时区,否则跨时区时间可能偏差 3600 秒(1 小时)
当时间含毫秒或微秒时,strtotime() 会丢弃精度
比如 "2024-04-01 10:20:30.123" 传给 strtotime(),返回的时间戳只精确到秒,小数部分被直接截断。如果你需要毫秒级差值,不能只靠 strtotime()。
- PHP 7.3+ 可用
DateTimeImmutable::createFromFormat()配合getTimestamp()和format('u')拆出微秒再拼接 - 更简单稳妥的做法:改用
DateTime对象相减,再调用getTimestamp()和format('u')手动算总微秒差,最后除以 1000000 得秒数(带小数) - 注意:
DateTime::diff()返回的DateInterval对象不直接提供总秒数,$interval->s只是“秒字段”,不含分钟/小时换算
用 DateTime 对象做减法更可控,尤其处理时区和夏令时
如果时间来自不同地区(比如日志记录 UTC,用户输入本地时间),或涉及夏令时切换日(如 3 月第二个周日),strtotime() 的隐式时区行为容易翻车。用 DateTime 显式指定时区,能避免多数意外。
立即学习“PHP免费学习笔记(深入)”;
- 写法示例:
$start = new DateTime('2024-03-10 01:59:00', new DateTimeZone('America/New_York'));<br>$end = new DateTime('2024-03-10 03:01:00', new DateTimeZone('America/New_York'));<br>$diff = $end->getTimestamp() - $start->getTimestamp(); // 得到真实经过的秒数 - 别用
$end - $start(对象不能直接减),也别依赖diff()的%s格式化——它只输出区间描述,不是数值 - 如果两个时间本就同属一个时区且无夏令时跳跃,
strtotime()足够;一旦有不确定性,DateTime是更少惊喜的选择
注意 strtotime() 的相对时间解析陷阱
strtotime("next Monday") 或 strtotime("+1 day") 这类相对表达,在计算差值时容易引发歧义——它们基于当前时间解析,不是固定时间点。若你在循环里反复调用,每次基准不同,结果就不稳定。
- 例如:
$now = time(); $tomorrow = strtotime('+1 day');,如果这两行之间隔了几毫秒,$tomorrow - $now可能是 86400,也可能是 86401(闰秒或系统时钟调整) - 生产环境建议:先统一用
new DateTime()获取当前时刻,再用modify()推算目标时间,保证基准一致 - 调试时可打印
date('c', strtotime($t))看实际解析出的时间,比猜强得多
时间差计算看着简单,真正卡住人的往往不是公式,而是时间字符串是否真被正确理解、时区有没有悄悄偏移、以及“一秒”在系统层面到底指哪一秒。











