Keeping Time in Javascript, March 31, 2013

When writing Javascript code, I seldom have the need to precisely factor time into my code. Recently, I had a task to do that took what I thought I knew about keeping time in Javascript and threw it out the window.

Let's suppose, for the sake of discussion, that I am writing Javascript code for a web application that displays a stock ticker. One of my requirements is to display, at all times, what time it is in New York. Any solution that depends on the user's clock being set correctly is out of the question. Suppose further, that this application must work in Internet Explorer 8 and 9 because the manager of the project expects that most everyone using the web application will use one of these browsers. Let's also suppose for the sake of discussion that the time in New York is May 21, 2010 at 2:00 PM.

The first idea I try is to use the Javascript setInterval function.

The above solution is very simple. The code to look up the time and describe how to display it is actually longer than the code to keep time. However, this solution does not measure up in a real-world web application. There are two particular problems that this does not address.

First, even though you can specify any length of time to setInterval, the timing of the execution of the code is not guaranteed to be exact. In one test with Internet Explorer 8 where the application was left open overnight, the clock got off by about fifteen minutes! Also, this solution does not take into account the fact that Javascript is single-threaded (barring the use of HTML 5 Web Workers). See for your self. Click here to open a modal dialog box and see that this stops the clock and causes it to loose the time.

Another solution that I tried was to have the system check the system clock each time the tick function executes and adjust the amount of time until the next tick accordingly. This was a bit more complicated, and ultimately didn't work much better than the above solution in my tests.

What I eventually tried that did work was to use the system clock on the Javascript client to keep track of two offsets. The first offset is the difference between the time on the server clock and the time on the client clock. The second is the difference between when the tick function is executing now and what time it was when the previous execution took place, which should generally be about 1000 milliseconds. When this time deviates from 1000 milliseconds, we can factor in the deviation when determining when the next tick should occur.

Do bear in mind, though, that in this more advanced solution, the tick function is not being used to keep track of the actual time. Instead, the tick function is used only to update the display time, which is accomplished by taking the current time on the client's clock and adding back the offset that we computed at the beginning.

This more advanced way of tracking the time has the distinct advantage that no matter how much Javascript is executing in other parts of the program, (Click here for another modal dialox) the clock will not lose the time. Even though other Javascript code may interfere with the tick function executing once per second, such as in the case of a modal dialog, when the tick function resumes, it will display the correct time again.

There is one definite pitfall with this solution, however. Although we don't count on the client clock to have the correct time when the code starts, we do count on the client clock accurately tracking how many milliseconds have elapsed. In other words, the user can still make this program behave erratically by changing the client clock as the program runs.