You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript转PHP日期计算代码返回值不匹配,请求排查问题

JS与PHP日期差值计算结果不匹配问题排查

问题描述

我尝试将以下JavaScript日期计算代码转换为PHP代码,但两者返回的日期差值结果不匹配。

JavaScript代码

d1 = new Date("2022-01-13 00:00:00");
d2 = new Date();
d2.setTime(1641951202187.3433);  

console.log(d1,d2)
console.log(d1-d2); // 返回值60997813

PHP代码

date_default_timezone_set("Asia/Kolkata");   //India time (GMT+5:30)

$d1 = new DateTime("2022-1-13 00:00:00");
$mili = 1641951202187.3433;
$sec = $mili /1000;
$d = date('M-d-Y H:i:s',$sec);
$d2 = new Datetime($d);
$s1 = (strtotime($d1->format('d-m-Y H:i:s'))*1000)-(strtotime($d2->format('d-m-Y H:i:s'))*1000);

echo "Value of s1 =  ".$s1;

PHP返回值为60998000,与JavaScript的返回值不匹配,请问哪里出错了?


问题原因

你的代码存在两处关键问题,导致精度丢失:

  • 毫秒精度被丢弃:用date('M-d-Y H:i:s',$sec)格式化时间时,该格式只保留到秒,直接丢掉了毫秒部分,使得d2的时间被四舍五入,最终差值出现偏差。
  • 多余转换引入误差:把DateTime对象转成字符串再用strtotime解析,这个过程完全没必要,还可能因为格式解析问题引入额外误差。

修正后的PHP代码

直接基于毫秒时间戳创建DateTime对象并计算差值,全程保留毫秒精度:

date_default_timezone_set("Asia/Kolkata");

$d1 = new DateTime("2022-01-13 00:00:00");
$mili = 1641951202187.3433;

// 直接解析带毫秒的时间戳,保留完整精度
$d2 = DateTime::createFromFormat('U.u', sprintf('%.6F', $mili / 1000));
$d2->setTimezone(new DateTimeZone('Asia/Kolkata'));

// 计算两个时间的毫秒级差值
$diffMs = ($d1->getTimestamp() * 1000 + $d1->format('u') / 1000) 
         - ($d2->getTimestamp() * 1000 + $d2->format('u') / 1000);

echo "Value of s1 = " . round($diffMs); // 输出60997813,与JS结果一致

关键说明

  • DateTime::createFromFormat('U.u', ...)可以直接解析包含毫秒的时间戳,避免字符串格式化丢失精度。
  • 通过getTimestamp()获取秒数,结合format('u')获取微秒值并转换为毫秒,确保计算时保留完整的时间精度。
  • 用round()处理浮点运算的微小误差,得到和JavaScript完全一致的结果。

内容的提问来源于stack exchange,提问作者Navdeep Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:36:25