有时,我们会收到用户的报告,称应用程序中的倒数计时器设置得太高或显示负数。我发现这是一个时区问题,但是即使更改计算机BIOS中的时钟设置,也无法通过更改时钟设置来复制它。我能够复制它的唯一方法是在代码中实际从时间戳中添加或减去3600秒。

我读到Date().getTime()总是提供UTC时间戳。我怀疑它是从Internet上获得的,所以对我来说,如果计算机提供的时间不正确,那可能是错误的。不幸的是,我还无法真正实现这一目标。

我也无法在网上找到太多有关此的信息,也无法从我们的用户那里收集任何数据(这种情况很少见,一旦提到时区和系统时钟,他们就不愿意提供帮助就不足为奇了)。

那么,JavaScript可以为我提供不正确的UTC时间戳吗?如果是这样,是否有确保时间戳准确的策略?

编辑-
令我惊讶的是,最简单的解决方案可能只是发送服务器时间并使用它,因为它不需要特别准确。

最佳答案

我想说的是,如果您想深入研究实现-请检查Mozilla代码。它是开源的。由于您的帖子,我对其进行了深入研究,最终到达了文件:https://hg.mozilla.org/mozilla-central/file/tip/js/src/vm/Time.cpp

它具有一些有趣的功能,称为NowCalibrate()。如果关闭系统时间或其他原因,似乎可以解决固定时间问题。
您可以检查79至140行。我将附加部分代码以初始化时间。

void
PRMJ_NowInit()
{
    memset(&calibration, 0, sizeof(calibration));

    // According to the documentation, QueryPerformanceFrequency will never
    // return false or return a non-zero frequency on systems that run
    // Windows XP or later. Also, the frequency is fixed so we only have to
    // query it once.
    LARGE_INTEGER liFreq;
    DebugOnly<BOOL> res = QueryPerformanceFrequency(&liFreq);
    MOZ_ASSERT(res);
    calibration.freq = double(liFreq.QuadPart);
    MOZ_ASSERT(calibration.freq > 0.0);

    InitializeCriticalSectionAndSpinCount(&calibration.data_lock, DataLockSpinCount);

    // Windows 8 has a new API function we can use.
    if (HMODULE h = GetModuleHandle("kernel32.dll")) {
        pGetSystemTimePreciseAsFileTime =
            (void (WINAPI*)(LPFILETIME))GetProcAddress(h, "GetSystemTimePreciseAsFileTime");
    }
}


另一方面,我发现其他所有浏览器都有其自己的实现,但是Mozilla可以成为现实世界的示例,说明在特定时间段后如何计算和校准初始时间。

10-07 19:11
查看更多