Nathan
Nathan

Reputation: 21

Can Javascript's Date().getTime() be incorrect if the system clock is wrong?

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

Answers (1)

Vitalii Chmovzh
Vitalii Chmovzh

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

Related Questions