Reputation: 21
Occasionally we get a report from users that a countdown timer in our application is set too high, or is displaying negative numbers. I figured it was a timezone issue but I've been unable to replicate it by changing my clock settings - even if I change the ones in my computer's BIOS. The only way I was able to replicate it was by actually adding or subtracting 3600 seconds from the timestamp in my code.
I read that Date().getTime()
always provides a UTC timestamp. I doubt it's sourced from the internet, so it makes sense to me that it could be wrong if the computer is providing an incorrect time. Unfortunately I can't make this actually happen yet.
I also can't find much information online about this, or gather any data from our users (This is very infrequent and they unsurprisingly become unwilling to help once I mention timezones and system clocks).
So, can Javascript provide me with an incorrect UTC timestamp? If so, is there a strategy to ensure the timestamp is accurate?
Edit - It struck me that the simplest solution is probably just to send over the server time and use that, since it doesn't need to be especially accurate.
Upvotes: 1
Views: 1634
Reputation: 2943
I'd say if you want to dig into implementation - go and check Mozilla code. It's open source. I dig into it because of your post and I finally reach to the file: https://hg.mozilla.org/mozilla-central/file/tip/js/src/vm/Time.cpp
It has some interesting function called NowCalibrate()
. Seems that it's doing the trick with fixing time if the system time is off or something.
You can check lines 79 to 140. I will attach portion of the code that initializes the time.
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");
}
}
On the other side I found that every other browser has it's own implementation, but Mozilla can be a real world example of how the initial time can be calculated and calibrated after certain period.
Upvotes: 1