
Properly calculating time differences in JavaScript - VMG
http://blog.synyx.de/2012/11/properly-calculating-time-differences-in-javascript/
======
geuis
This is good info.

I'm a fairly intelligent guy, can follow the plots of Primer, Terminator, and
other scifi time travel movies. I have a decent understanding of relativity,
spatial reference frames, etc.

But any time I have to deal with slightly more-than-simple time issues in any
language, my brain starts more or less falling to pieces. Python and js have
good libraries that help, but its still a confounding bugger of an issue.

~~~
tadfisher
It's pretty simple once you know the rules:

\- Always store times and calculate differences/offsets in UTC.

\- Never attempt to convert a local time to UTC (it is _not_ a one-to-one
mapping!).

\- Depending on your application, convert any dates to a given timezone _at
the moment they are displayed_.

Now Javascript throws a monkey-wrench into the whole affair, because it
assumes Dates should be handled in the user's local timezone, which, if you're
dealing with timezone issues, is certainly not what you want. So attempting to
convert a Date object from one timezone to the next is surely impossible to do
without introducing bugs unless you understand the rules for every timezone
you're dealing with.

Luckily, a guy named Olson created a database of timezone rules for us mortals
to use in our timezone-aware applications. In another stroke of good fortune,
some smart people wrote a Javascript library [1] that parses this database for
you and can convert your Javascript Date object between any timezone on the
planet. So you do all your calculations using this Date object in UTC mode,
then convert to the desired timezone at the time they are displayed.

[1] <https://github.com/mde/timezone-js>

------
tomjakubowski
Nitpicking, but this:

 _Luckily, there is, and that place is UTC. UTC is a time measuring system
that does not have daylight savings time and where midnights always are 24
hours apart._

isn't strictly true, at least in the sense that 24 hours isn't always the same
length of time because of leap seconds.

~~~
VMG
The ECMA-262 luckily(?) ignores leap seconds:

<http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.1>

 _Time is measured in ECMAScript in milliseconds since 01 January, 1970 UTC.
In time values leap seconds are ignored. It is assumed that there are exactly
86,400,000 milliseconds per day._

~~~
adg001
Ignoring leap seconds will not make them disappear :-) They belong to UTC not
to ECMA-262.

Therefore, whenever we compute the difference between two UTC times, we should
really account for any leap second.

~~~
VMG
For the purpose of calculating milliseconds between midnights of different
days, you can however assume them to be multiples of 862e5 _in JavaScript
Date.UTC_.

You just have to keep in mind that JavaScript UTC != Real UTC

Edit: clarification

~~~
adg001
No, you cannot. If you do it, your UTC time difference might be one or more
seconds off. And this is not what you want, if you need to rely upon that
quantity.

Only one Coordinated Universal Time exists: it is the UTC standard. ECMA-262
is the specification of a scripting language, with tons of interesting
features but with a very poor understanding of what UTC is.

UTC is based on TAI. Whenever we need to compute time differences of UTC
times, we need to account for leap seconds implementing TAI. Implementations
are available in a number of languages and very easy to port: \- C
<http://cr.yp.to/libtai.html> \- Haskell
[http://hackage.haskell.org/packages/archive/time/1.4/doc/htm...](http://hackage.haskell.org/packages/archive/time/1.4/doc/html/src/Data-
Time-Clock-TAI.html) \- Erlang <https://github.com/secyoure/taider>

Full disclosure: author of the Erlang TAI library here.

~~~
VMG
I completely agree - but as you point out, JavaScript doesn't use proper UTC
but a simplified version that does not account for leap seconds. Let's call it
Date.UTC.

In Date.UTC, there are no leap seconds and therefore the Day == 862e5
assumption holds and we can use it to calculate the difference between two
dates measured in days, which is the point of the blog post.

When doing arithmetic with _real_ UTC, you are absolutely correct and we have
to take leap seconds into account.

------
arnarbi
If you don't mind dependencies, there's Moment.js

<http://momentjs.com/>

~~~
tadfisher
...Which unfortunately falls short when you need to do anything more
complicated than transforming dates between local time and UTC. If you need
to, say, display a Date in Pacific Standard Time to a user agent in Helsinki,
you absolutely need something that understands the timezone database.

I've found that timezone-js [1] does the job.

[1] <https://github.com/mde/timezone-js>

------
inetsee
When I ran into this problem, I ended up switching over to using the "datejs"
library, located here "<http://code.google.com/p/datejs/downloads/list>.
Date.js seems to handle Daylight Savings Time just fine; I don't know if it
deals with Leap Seconds.

------
kevincennis
"As a JavaScript veteran you know that you have to use new Date() instead of
Date() because the second one returns a string for some reason"

Uhhhhh...

