javascript - JavaScript 中的时间戳不一致?

标签 javascript date timestamp

我在 JS 中的 Date.now() 函数中遇到了一些奇怪的错误。

背景信息:我正在开发一个 web 应用程序,用于向服务器发送数据包或从服务器接收数据包。我所有传入的数据包都标有由 Date.now() 生成的时间戳。这些数据包中有数据,被打印成折线图。所以我在 y 轴上得到一个值,在 x 轴上得到时间戳。到目前为止一切顺利。

让应用程序运行给我带来了一些奇怪的行为 -> 我的折线图有时会在已经存在的数据点之前绘制过去的数据点!在检查这些点的时间戳时,我发现我的图表一切正常,但时间戳是错误的。

所以我写了一个小测试脚本,以收集更多证据:

var i = 0;
var ts = [Date.now()];

setInterval(function () {

    ts.push(Date.now());

    console.info("checking next timestamp ...");

    if (ts[i] > ts[i+1]) {

        console.error("old timestamp (" + ts[i] + ") is BIGGER than current timestamp (" + ts[i+1] + ")!");
    }

    i++;

}, 100);

运行几分钟会打印一个错误:

Chrome DevTools Console Error 1

很久以后我又得到了一个,依此类推。

Chrome DevTools Console Error 2

对于这个测试,我选择了 100 毫秒的间隔时间来检查许多时间戳。但我的应用程序的更新间隔可能是 5 秒,有时仍然会出现此错误。虽然不像 100 毫秒那样频繁,但它确实存在:(

以前有其他人见过这种行为吗?我在这里做错了什么吗?

顺便说一句:我的应用程序中的数据包是一一进来的,因此不可能出现数据包顺序混淆或其他问题。

最佳答案

嗯,正如我昨天研究过 Performance API 一样,我认为这是正确的方法。我在我的应用程序中实现了它,如下所示:

每次当我从服务器收到输入数据包时,我都会给它们一个时间戳。到目前为止,我已经通过 Date.now() 意识到了这一点,但这似乎不一致,因为操作系统或虚拟机(或两者)不时重新计算其当前时间。

所以现在我计算自己的时间戳。为此,我必须读取应用程序启动时的时间戳。性能 API 为我提供了这个值

var startTS = window.performance.timing.navigationStart; //returns a timestamp in ms

所以这是我的应用程序中随处可用的值,因为它存在于窗口命名空间中并且不需要我自己创建的全局变量。非常好。

现在,要获取当前时间戳,我必须添加一个时间值,该值指示我的应用程序自 startTS 以来运行了多长时间。为了得到这个,我们只需使用:

var timeSinceStartup = window.performance.now(); //returns sth. like 1337.9836718 (ms with fractional part)

如果需要,可以将此值舍入,因为可能不需要小数部分:

var rounded = (timeSinceStartup + 0.5) | 0; //same as but faster than Math.round(timeSinceStartup);

好吧,剩下的就很简单了。我们只需添加这些值(因为两者都是毫秒),瞧:

var currentTS = startTS + timeSinceStartup;

我已经更新了我的问题中的小代码片段来测试这一点:

var i = 0;
var start = window.performance.timing.navigationStart;
var ts = [start + window.performance.now()];

setInterval(function () {

    ts.push(start + window.performance.now());

    console.info("checking next timestamp ...");

    if (ts[i] > ts[i+1]) {

        console.error("old timestamp (" + ts[i] + ") is BIGGER than current timestamp (" + ts[i+1] + ")!");
    }

    i++;

}, 100);

Chrome 目前正在运行此测试(在虚拟机中),看起来一切都很好(17500 个检查没有错误)。我想知道是否某事。否则会发生,因为我们只是添加一个具有单调上升值的常量;)

此解决方案的唯一缺点似乎是浏览器支持。到目前为止,除 Safari 之外的所有现代浏览器都支持此功能。由于我的应用程序开发为仅在现代浏览器上运行,这对我来说没问题,但缺少 Safari 就很糟糕了。

http://caniuse.com/#feat=high-resolution-time

我将不得不研究一下跨浏览器解决方案/polyfills/框架或其他东西。感谢大家的帮助。不管怎样,我仍然很好奇 Chrome 中是否有 Date.now() 的解决方案,因为 FF 和 IE 使用它没有任何问题。

https://code.google.com/p/chromium/issues/detail?id=408077

编辑

这对于缺少性能 API 来说似乎是一个很好的填充: https://gist.github.com/paulirish/5438650

当然,它会回退到 Date.now(),因此在不支持 API 的浏览器中我可能会遇到与以前相同的问题。对于这种情况,我只是不断检查应用程序中的时间戳,如果发生计时错误,我将默默地处理它(例如,不要将其绘制到图表中,而是等待下一个值)。

再见...

关于javascript - JavaScript 中的时间戳不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25524471/

相关文章:

javascript - ToggleShow 元素只在这个特定的div中点击显示

javascript - 如何在自定义日期的输入文本中输入最小值和最大值

java - Hibernate 多对多映射附加列时间戳

javascript - 有没有更优雅的方法从数组中删除元素?

javascript - 使用 jQuery 向服务器发出请求

javascript - Fullcalendar js 和 Firefox 中的日期无效,如何处理?

java - 新的 Date() 对象给出相同的值

mysql - 德尔福/MySql : timestamp in DB aware components

javascript - Moment JS - UTC 与本地时间戳比较失败

javascript - 如何在 d3 树布局节点中包含添加、编辑和删除按钮?