Accuracy of the Date object

We often find ourselves using 'Date.now()' twice and comparing the numbers to get the duration of time that has passed. Or in ye' olden times the IE 7 compatible "new Date().getTime()". It's easy to assume that something sensible happens when we make these calls, but alas, that is not our lot in life. Making comparing two times one of the JavaScript Common Pitfalls.

The first, and most obvious problem is that time in JavaScript is not monotonic. It's only reported to the nearest millisecond, so if you call "Date.now()" twice within a millisecond, it reports the same time. This is mostly a problem if you want to use time as part of some sort of key/tagging situation. So, never rely on Date.now() being unique.

The bigger, hidden, problem is that Date.now() relies on the operating system for it's time. That may not sound bad on the surface, but who regulates the behavior of the time that the operating system reports to JavaScript? Nobody, that's who.

So, if system time is altered in between two call Date.now() we have a meaningless relationship without even knowing it. We can even have cases where it appears that now is negative milliseconds after some time in the past. That is a really unhelpful result. And most systems have their time automatically adjusted regularly by services out of everyones control, it's not just a mischievous user setting the clock back to fool your timing, but automation who's sole job is to monkey with the system clock.

The accuracy is also entirely arbitrary. In most modern operating systems you'll get 1ms accuracy, as close as the JS Date object can handle anyway. However, a lot of people still run windows XP, and XP has a shockingly bad 15ms minimum time resolution. That's right, time steps in 15ms blocks as far as Date.now() is concerned on an XP machine. Bleh. This really compounds that uniqueness problem above too.

So, this is pretty bleak right? Well, only if you need to support old browsers (or Mobile Safari...), the rest of the environments have high resolution time! In Node it's 'process.hrtime()', and in the browser it is 'performance.now()'. These both offer high resolution, and a genuine guarantee that two high res times will have meaning relative to each other. Keep in mind these are both relative times though, not absolute, so don't think you can go replace all of your Date objects!