Setting timezone in MomentJS
Asked Answered
I

1

8

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?

Insoluble answered 12/11, 2015 at 9:40 Comment(2)
That doesn't sound like a good idea. The actual timezone offset of the Date instance is still whatever it gets from the host system, but when trying to read it you'll get 120 (minutes), equivalent to UTC-02:00. To get times in other timezones, moment.js should be using UTC methods and applying an appropriate offset, but you'll need to look at the source to determine that.Loganiaceous
So should I use TimeShift.js ?Insoluble
K
9

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.

Kruse answered 12/11, 2015 at 17:19 Comment(3)
can I use just moment-timezone without momentjs? I mean, just for setting the timezone to a fixed one.Insoluble
No, it doesn't work that way. moment-timezone extends moment. You need them both.Kruse
Nice answer + proof! ThanksElviselvish

© 2022 - 2024 — McMap. All rights reserved.