有时,我们会收到用户的报告,称应用程序中的倒数计时器设置得太高或显示负数。我发现这是一个时区问题,但是即使更改计算机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可以成为现实世界的示例,说明在特定时间段后如何计算和校准初始时间。