4

In Vanilla JavaScript (i.e. without using Moment.js).

I have a server returning a timezone string, like Asia/Tokyo America/New_York etc... That timezone is independent from the user current timezone. So the server can return Asia/Tokyo when my current OS timezone is America/New_York

from the server given timezone, I would like to format it to something like =>

UTC+09:00 Asia/Tokyo

So in simple, I just want, from a given timezone, to find the UTC Offset of that timezone.

There is a native function getTimezoneOffset in JS, but I can't find a setTimezone

I tried to do something like

var d = new Date()
new Date(d.toLocaleString('en-US', { timeZone: 'Asia/Tokyo' })).getTimezoneOffset()

but this always return my current offset.

How can I do this ?

7
  • Timezone is independent of the current timezone? can you elaborate?
    – its4zahoor
    Commented Aug 11, 2020 at 7:47
  • Native JavaScript APIs don't have support for any timezone other than the local one (i.e. whatever the user has set their OS to) and UTC. Commented Aug 11, 2020 at 7:49
  • 2
    @its4zahoor basically if I am in america/newYork, and the server give Asia/Tokyo I want to have the offset of Asia/Tokyo based on UTC and not on my current timezone (america/newYork)
    – Crocsx
    Commented Aug 11, 2020 at 8:00
  • @JoachimSauer so you say I can only get the utcoffset of my localtimezone to UTC, but I can't get the offset of all the other (still supported by date) timezone to UTC ?
    – Crocsx
    Commented Aug 11, 2020 at 8:01
  • @Bobby: I'm no JavaScript expert, but from looking at the Date API, I don't see any support for specifying (or querying) any other time zones. What makes you think others are "still supported by date"? Commented Aug 11, 2020 at 8:17

1 Answer 1

4

You can use Date.toLocaleString() to calculate this, this solution is slightly hacky, since we're formatting a date, then parsing. But it should do what you wish.

I'm converting to the "sv" date format, since it's very similar to ISO-8601, then parsing to get the UTC date.

Note: The offset will be negative for timezones east of the Greenwich meridian, this is the same as the IANA convention. You can simply reverse if you wish to get UTC offset as minutes ahead of UTC. Also, I'm rounding at then end, since our original date will contain a millisecond component that we're not interested in.

function getUTCOffset(date, timeZone) {
    const dateComponents = date.toLocaleString("sv", { timeZone }).split(/[\-\s:]/);
    // Months are zero-based in JavaScript
    dateComponents[1] = dateComponents[1] - 1;
    const utcDate = Date.UTC(...dateComponents);
    return Math.round((date - utcDate) / 60 / 1000);
}

console.log(getUTCOffset(new Date(), 'Asia/Tokyo'));
console.log(getUTCOffset(new Date(), 'America/Los_Angeles'));

4
  • 1
    I see, yeah a bit patchy, but I guess it works and apparently native date can't do much better. Thank you
    – Crocsx
    Commented Aug 11, 2020 at 8:05
  • I think this is about the only way to to this in native JavaScript, I'm not aware of any others! Commented Aug 11, 2020 at 8:06
  • 1
    Keep in mind that the offset calculated this way depends on the current time of year and can change due to daylight saving time. If this is used for indication in the UI, it can be confusing to the user. And if it's used for any other functionality, it can cause ugly bugs. Commented Aug 11, 2020 at 8:22
  • That's a good point, @JoachimSauer, the UTC offset will vary if the timezone in question uses DST. Commented Aug 11, 2020 at 8:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.