<p>microtime(true) 是获取微秒级时间戳的正确方式,返回浮点数如 1718923456.123456;round(microtime(true) * 1000000) 得标准 Unix 微秒时间戳,精度高、兼容性好、与时区无关。</p>

PHP microtime() 返回值格式容易搞错
microtime() 是唯一能直接获取微秒级时间的内置函数,但它默认返回字符串而非数字,形如 "0.12345600 1718923456"(小数部分是秒的小数,整数部分是 Unix 时间戳)。很多人直接用 (int) microtime() 或 intval(microtime()),结果得到 0 —— 因为字符串开头是小数点,强制转整会截断成 0。
正确做法是传入 true 参数,让它直接返回浮点数:
echo microtime(true); // 输出类似 1718923456.123456
这个浮点数乘以 1000000 后再取整,就是标准的微秒时间戳(自 Unix 纪元起的微秒数):
-
round(microtime(true) * 1000000)是最常用、兼容性最好的方式 - 不要用
floor()或intval(),它们在负数或边界值时可能向下取整出错 - PHP 8.0+ 支持
hrtime(true),但返回的是纳秒,且不是 Unix 时间戳起点,需额外换算,不推荐用于“当前时间戳微秒”这一明确需求
为什么不用 DateTime::getTimestamp() 或 time()
这两个函数只精确到秒:time() 返回 int 类型秒级时间戳;DateTime::getTimestamp() 同样只返回秒。即使你用 DateTime::format('u') 能拿到微秒(000000–999999),它只是当前秒内的微秒偏移,不是完整的时间戳。
立即学习“PHP免费学习笔记(深入)”;
常见错误写法:
$dt = new DateTime();
$ts = $dt->getTimestamp() . $dt->format('u'); // 错!拼接后是字符串,且不是数值时间戳如果硬要组合,得这样算:
$dt = new DateTime();
$microseconds = $dt->getTimestamp() * 1000000 + (int)$dt->format('u');但比 round(microtime(true) * 1000000) 多一次对象创建和格式化,性能差、代码冗长,没理由选它。
注意时区对 microtime() 没影响
microtime(true) 基于系统底层 gettimeofday() 或 clock_gettime(),返回的是 UTC 时间对应的浮点秒数,与时区设置(date_default_timezone_set())完全无关。所以你不需要、也不应该为了“获取当前时间戳微秒”去设置或切换时区。
容易混淆的点:
-
date('u')或DateTime::format('u')输出的微秒值,是本地时区下该秒内的偏移,但microtime()不走这套逻辑 - 如果你需要带时区语义的“某时区当前时刻的微秒时间戳”,那本质是「先确定该时区此刻对应 UTC 的秒数,再加微秒」——而
microtime(true)已经是那个 UTC 秒数了,直接用即可
实际使用中的精度与误差
PHP 的 microtime(true) 在 Linux 上通常基于 CLOCK_MONOTONIC 或 CLOCK_REALTIME,实际分辨率取决于系统,常见为微秒级,但不保证每次调用都严格递增(尤其在虚拟机或高负载下可能抖动)。
关键提醒:
- 两次连续调用
microtime(true)相减,不能保证结果 ≥ 0 —— 可能出现 -0.000001 这种负值,做差值计算时建议用max(0, $end - $start) - 若用于生成唯一 ID(如订单号、日志 trace_id),不要只依赖
microtime(true),必须叠加进程 ID、随机数或序列号防冲突 - Web 请求中,PHP 脚本启动到执行
microtime(true)之间已有毫秒级延迟,别把它当成“请求抵达的绝对瞬间”
微秒时间戳本身没有“时区”,也没有“格式”,它就是一个大整数。怎么解析、怎么存储、要不要转成字符串,取决于你的下游系统是否认这个数值单位 —— 别在 PHP 层过度封装。



















