php处理13位毫秒级时间戳需先判长为13且值合理,再整除1000转为10位秒级时间戳;若需毫秒精度,须单独提取余数并用datetime手动添加毫秒。

PHP里遇到13位时间戳,先判断是不是毫秒级
PHP原生的 date()、strtotime()、mktime() 全部只认10位时间戳(单位:秒),13位基本是JavaScript或Java系传来的毫秒级时间戳。直接用会返回 false 或错误日期(比如1970年)。
常见错误现象:date('Y-m-d', 1717027200000) 输出 1970-01-01;strtotime('1717027200000') 返回 false。
- 先检查长度:用
strlen((string)$ts) === 13快速识别 - 再验证合理性:13位数若大于
1000000000000(约2001年),基本可确认是毫秒级 - 别用
(int)$ts / 1000强转——浮点精度可能丢毫秒,比如1717027200123 / 1000在32位系统上可能变成1717027200.1229999,取整后少1秒 - 稳妥做法是用
(int)($ts / 1000)或intval($ts / 1000),确保截断而非四舍五入
转换成标准时间或DateTime对象
拿到10位秒级时间戳后,就能正常交给PHP处理。但注意:如果后续要保留毫秒精度(比如存入MySQL的 DATETIME(3)),得单独提取毫秒部分。
示例:
$ms_ts = 1717027200123;
$sec_ts = (int)($ms_ts / 1000); // 1717027200
$ms_part = $ms_ts % 1000; // 123
<p>// 标准格式(无毫秒)
echo date('Y-m-d H:i:s', $sec_ts); // 2024-05-30 00:00:00</p><p>// 带毫秒的格式(需手动拼)
$dt = new DateTime("@$sec_ts");
$dt->modify("+{$ms_part} milliseconds");
echo $dt->format('Y-m-d H:i:s.v'); // 2024-05-30 00:00:00.123
</p>
-
DateTime("@$sec_ts")是最干净的构造方式,比date_create("@$sec_ts")更明确 - 避免用
date('Y-m-d H:i:s') . '.' . str_pad($ms_part, 3, '0', STR_PAD_LEFT)拼接——时区不一致时容易出错 - 如果只是做比较或计算,通常不需要还原毫秒,
$sec_ts足够用
接收前端传来的13位时间戳时的防御写法
接口常收JSON里的 "timestamp": 1717027200123,不能假设前端一定传对。需要校验+兼容。
- 用
is_numeric()+is_int()或ctype_digit()判断是否为纯数字字符串,防注入 - 长度为13且值在合理范围(比如 > 1000000000000 &&
- 长度为10,直接当秒处理;其他长度(如14位)要警惕——可能是带微秒或格式错误
- 推荐封装一个安全转换函数:
function normalizeTimestamp($ts): ?int {
if (!is_numeric($ts)) return null;
$ts = (string)$ts;
$len = strlen($ts);
if ($len === 10 && ctype_digit($ts)) {
return (int)$ts;
}
if ($len === 13 && ctype_digit($ts) && $ts > '1000000000000') {
return (int)($ts / 1000);
}
return null;
}
MySQL存13位时间戳要注意时区和字段类型
PHP转成10位后插入MySQL,看似没问题,但容易忽略两点:一是MySQL的 UNIX_TIMESTAMP() 函数返回的是本地时区秒数,二是 DATETIME 字段不保存时区信息。
- 存秒级时间戳推荐用
INT(10),比TIMESTAMP更省空间、无2038问题 - 如果必须存毫秒级,用
BIGINT存原始13位值,或用DATETIME(3)+ PHP侧生成带毫秒的字符串 - 从MySQL读出来的时间再转回13位?别用
UNIX_TIMESTAMP(col) * 1000——如果col是DATETIME类型,它本身不含时区,而UNIX_TIMESTAMP()会按MySQL时区转成UTC秒数,结果可能偏移 - 更稳的方式:查出
DATETIME字符串,用new DateTime($str)->getTimestamp() * 1000 + $ms_part还原(前提是存的时候记录了毫秒)
毫秒精度在PHP里不是“开箱即用”的能力,关键在识别来源、截断方式、时区上下文这三点。漏掉任意一个,时间就悄悄跑偏几秒甚至几小时。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











