Get Timezone Offset Of Another Timezone In Javascript Without Using Strings
Solution 1:
You can't use time zone abbreviations reliably for input, as they can be interpreted in many different ways. For example, CST
might be either "Central Standard Time" in North America, or "China Standard Time", or "Cuba Standard Time". While some abbreviations like WET
and WEST
are unique, many are ambiguous. Refer to the list of time zone abbreviations here.
Instead, you need to know the IANA time zone identifier. One location that uses WET/WEST is Portugal, which as the IANA identifier of "Europe/Lisbon"
. You can find a list of identifiers here. Picking the correct identifier is important, as time zones change over time. Each identifier reflects the particular history of each region.
One you know the IANA time zone identifier, then you have options for how to use it:
In some modern browsers that fully support the time zone features of the ECMAScript Internationalization API (ECMA-402), you can do the following:
var d = newDate(); var s = d.toLocaleString(undefined, { timeZone: "Europe/Lisbon" })
This will convert the provided date and time to the correct time zone during formatting. Passing
undefined
in the first parameter will use the current locale for formatting.There are a few downsides to this approach, as it is not yet implemented in all browsers, and there is no API for just retrieving the raw time zone offset of a particular point in time.
You can consider using a library that implements this functionality. I list several of them here. My personal preference is for moment.js with the moment-timezone addon, which you can do the following:
var m = moment.tz("Europe/Lisbon"); var s = m.format();
You can pass parameters to the
format
method to display the output however you like. You can also convert an existing time, such as:var m = moment.utc("2016-01-01T00:00:00").tz("Europe/Lisbon"); var s = m.format();
You can also get the offset for a particular moment in time like so:
var m = moment.utc("2016-01-01T00:00:00").tz("Europe/Lisbon"); var offsetInMinutes = m.utcOffset(); var offsetAsString = m.format("Z");
You can write your own code for handling a particular time zone. Though this can be error prone and I don't generally recommend it. Updates can be particularly difficult if you go down this route.
Do also keep in mind that the offset for a particular time zone will vary depending on the date and time in effect. Therefore, new Date()
which represents "now" may or may not always be the correct input, depending on your scenario.
Solution 2:
I wanted to do this without using a library, so I wrote this function that gives you the timezone offset between the given timezone and utc:
functiongetTimezoneOffsetFrom(otherTimezone) {
if (otherTimezone === void0) { otherTimezone = "Europe/Amsterdam"; }
var date = newDate();
functionobjFromStr(str) {
var array = str.replace(":", " ").split(" ");
return {
day: parseInt(array[0]),
hour: parseInt(array[1]),
minute: parseInt(array[2])
};
}
var str = date.toLocaleString(['nl-NL'], { timeZone: otherTimezone, day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: false });
var other = objFromStr(str);
str = date.toLocaleString(['nl-NL'], { day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: false });
var myLocale = objFromStr(str);
var amsterdamOffset = (other.day * 24 * 60) + (other.hour * 60) + (other.minute);
var myLocaleOffset = (myLocale.day * 24 * 60) + (myLocale.hour * 60) + (myLocale.minute);
return myLocaleOffset - amsterdamOffset + date.getTimezoneOffset();
}
Maybe it can be approved by using en-US as a locale string and then the str.replace maybe needs to filter a comma or something.
Solution 3:
I wanted to without a library too, but even with moment it has a fixed amount of timezone data so will break after 30 years if you don't keep updating, just erks me a bit. although this does use strings, nothing more complicated than parsing a string which is just an number
functiongetTimezoneOffset(dt, timezone) {
let getItem = function(format) {
format.timeZone = timezone;
returnparseInt(dt.toLocaleString(
'en-US', format));
};
let adjDate = newDate(
getItem({year: 'numeric'}),
getItem({month: 'numeric'}) - 1, // months are zero basedgetItem({day: 'numeric'}),
getItem({hour: 'numeric',hour12: false}),
getItem({minute: 'numeric'}));
let noSecs = newDate(dt.getTime());
noSecs.setSeconds(0, 0);
let diff = Math.round((adjDate.getTime() - noSecs.getTime()) / 60000);
return dt.getTimezoneOffset() - diff;
}
Post a Comment for "Get Timezone Offset Of Another Timezone In Javascript Without Using Strings"