Why does JavaScript Date.getTimezoneOffset() consider "-05:00" as a positive offset?

I noticed that for us on Eastern Time zone ("America/New_York") with timezone offset of "-05:00" Date.getTimezoneOffset() returns a positive number of 300. I would expect offset in minutes to be negative in areas to the West from Utc, and to be positive in areas to the east of Utc, but apparently it's "flippded". What's the reasoning behind that decision?

http://momentjs.com/ follows the same rule and returns...

moment.parseZone("01/13/2014 3:38:00 PM +01:00").zone()   // == -60
moment.parseZone("01/13/2014 3:38:00 PM -01:00").zone()   // == 60

At the same time DateTimePicker http://trentrichardson.com/examples/timepicker/ does not flip numbers when setting its initial 'timezone' parameter. Is it wrong?


Solution 1:

Because that's how it's defined. Quoting the doc (MDN):

The time-zone offset is the difference, in minutes, between UTC and local time. Note that this means that the offset is positive if the local timezone is behind UTC and negative if it is ahead.

Solution 2:

Elaborating a bit on raina77ow's perfectly acceptable answer...

First, understand that the main standards involved here are ISO 8601 and RFC 822 (and its relatives 733, 1123 & 2822), which were all (in-part) derived from ANSI X3.51-1975.

All of these standards use the convention of positive values being East of UTC/GMT and negative values being West of UTC/GMT.

The only standard that I am aware of that has that reversed is POSIX (see the POSIX section of the timezone tag wiki, and this article), and thus explains why the backwards compatibility Olson time zones like "Etc/GMT+5" have their sign inverted. (Of course it's possible there are others usages and I am just unaware of them.)

Believe it or not, JavaScript does it BOTH ways. When used as a string (in either RFC 822 or ISO 8601 syntax) it uses hours and minutes with positive offsets East of UTC. But when calling the getTimezoneOffset() method on the Date object, it returns whole minutes that are positive West of UTC.

One can only speculate why this inconsistency exists. The ECMAScript spec is full of issues like this. Perhaps it's because when you see an offset in an ISO 8601 or RFC 822 string, that offset has already been applied. But when you call getTimezoneOffset() it's the offset to apply to bring it back to UTC.

For example, 2014-01-01T00:00:00-05:00 is equal to 2014-01-01T05:00:00Z. So getTimezoneOffset() would return 300. If you add 300 minutes to the original value, you get back to UTC.

It's two sides to the same coin. See?

In regards to whether or not that specific control is incorrect, I am not sure. I'm not familiar with that particular control. I see in their docs the example of -0400 being equal to -240, which one might expect to be reversed, but then again it's a bit strange to have a value like -240 presented to a user. Really, you shouldn't expose offsets to a user either way (IMHO). You're much better off using a time zone picker control, like this one or this one.