Setting timezone in MomentJS

Gianluca Ghettini picture Gianluca Ghettini · Nov 12, 2015 · Viewed 12.7k times · Source

I made some test code for my JavaScript SPA application. I set the locale for the entire SPA pretending to run it in different parts of the world.

Now, I set the locale overriding the getTimezoneOffset() function of the Date() class:

Date.prototype.getTimezoneOffset = function () { return 120 };

And it works fine.

However, in some part of the SPA I'm using MomentJS (due to some limitation of the standard DateTime library). Does the override affect the MomentJS locale as well? Or not?

Answer

Matt Johnson-Pint picture Matt Johnson-Pint · Nov 12, 2015

You should not override the Date object's getTimezoneOffset function. That actually won't work as you are expecting. It will just change how the offset is exposed through getTimezoneOffset, it won't change the behavior of the Date object itself, or the other function it has.

code

Above, you can see that despite changing the offset function, the date still uses Pacific time.

As far as moment.js goes, you certainly can set the offset of a moment object, using the utcOffset function.

var m = moment();
var o = m.utcOffset();  // returns the current offset
m.utcOffset(-120);      // sets a different offset

However:

  • The offset will have a sign that matches the ISO8601 standard, with positive values being east of UTC. JavaScript's getTimezoneOffset has positive values west of UTC.

  • Changing the offset only changes the values produced by moment itself, such as with the format function, and various other functions. It doesn't change the underlying moment in time, and thus if you call .toDate() to get a Date object, that object will have the original system time zone.

  • The Date object cannot be tricked into working in other time zones. Any approaches you may encounter that try shifting the time by the amount of the offset are flawed, and will fail in several edge cases.

  • An offset is not a time zone. Time zones can switch offsets for daylight saving time, and for other historical and political reasons. Read "Time Zone != Offset" in the timezone tag wiki. If your intent was to set a time zone, then you should use the moment-timezone plugin, and do something like:

    moment().tz('America/New_York')
    
  • You asked if your existing override would mess up moment.js - yes it will. moment uses the getTimezoneOffset function and expects it to be unaltered.