php生成毫秒时间戳需用microtime(true)乘1000并四舍五入取整,即(int)round(microtime(true)*1000);strtotime()不支持毫秒数字解析,须先转为秒级再格式化;mysql存毫秒推荐datetime(3)配合from_unixtime()或bigint字段;js与php互通时须注意13位毫秒整数校验与单位换算。

PHP怎么生成带毫秒的时间戳
PHP原生的 time() 只返回秒级整数,没法直接拿到毫秒。真要毫秒级精度,得靠 microtime(true) —— 它返回浮点数,小数点后6位是微秒(不是毫秒),所以得自己换算。
- 用
microtime(true)获取浮点时间戳,比如1715823456.789123 - 乘以 1000 后取整,得到毫秒级整数:
(int) round(microtime(true) * 1000) - 别直接
(int)强转浮点数,会截断小数,导致少掉最多 0.999 毫秒 - 如果只是日志打点或内部排序,用浮点值本身也行;但存数据库或传给前端 json 时,整数更稳妥、无精度争议
strtotime() 能解析毫秒时间戳吗
不能。strtotime() 只认字符串格式的时间(如 "2024-05-16 14:30:00" 或 "+1 day"),对毫秒级数字毫无反应。你传个 1715823456789 过去,它会当成“1715年8月23日”来解析,结果完全错乱。
- 毫秒时间戳要转成可读时间,先除以 1000 得到秒级时间戳,再用
date('Y-m-d H:i:s', (int) ($ms / 1000)) - 如果毫秒部分要保留(比如显示“2024-05-16 14:30:00.789”),得手动拼接:
date('Y-m-d H:i:s', $sec) . '.' . str_pad($ms % 1000, 3, '0', STR_PAD_LEFT) - 注意时区:
date()受date_default_timezone_set()影响,而microtime(true)返回的是绝对 Unix 时间,不带时区
MySQL 存毫秒时间戳要注意什么
MySQL 的 DATETIME(3) 或 timestamp(3) 支持毫秒,但 PHP 插入时容易出错——不是字段不支持,而是你传的值类型或格式不对。
- 别把毫秒时间戳当字符串插进去,比如
"1715823456789";MySQL 会尝试转成日期,结果变成公元1715年 - 正确做法是:先转成标准时间字符串,用
FROM_UNIXTIME(1715823456.789)(注意带小数点)或者在 PHP 里生成date('Y-m-d H:i:s.u', $sec)(u是微秒,需补零到6位) - 如果用整数毫秒存到
BIGINT字段,没问题,但查询时做时间计算(比如BETWEEN)就得自己除 1000,且索引效率略低于原生时间类型 -
u格式符输出的是微秒(6位),不是毫秒(3位),所以date('Y-m-d H:i:s.v')才对应毫秒(PHP 7.3+ 支持v)
JavaScript 和 PHP 毫秒时间戳互通常见坑
JS 的 Date.now() 返回毫秒整数,PHP 的 microtime(true) 默认是微秒浮点数,两边直接比对或传递,差1000倍是常态。
立即学习“PHP免费学习笔记(深入)”;
- PHP 给 JS 传时间,用
(int) round(microtime(true) * 1000),确保是整数毫秒 - JS 给 PHP 传时间,接收端必须验证是否为 13 位数字(避免被当成秒级时间处理),比如加一层判断:
if (strlen((String)$ts) === 13) { $sec = (int) floor($ts / 1000); $ms = $ts % 1000; } - 注意 JS 的
new Date(1715823456789)和 PHP 的date('r', 1715823456)对应同一时刻,但 PHP 不会自动理解这个数字是毫秒 - 跨时区调试时,别只看时间字符串,优先比对原始毫秒数值,最可靠
毫秒本身不难,难在每个环节都默认按“秒”处理。只要记住:PHP 没有原生毫秒函数,所有毫秒操作都是基于 microtime(true) 的手工换算,且每一步的类型、精度、时区都得亲手控住。