Get utc offset from timezone in Javascript - javascript

I need a Javascript function that given a timezone, returns the current UTC offset.
For example, theFuncIneed('US/Eastern') -> 240

In general, this is not possible.
US/Eastern is an identifier for a time zone. (It's actually an alias to America/New_York, which is the real identifier.)
240 is a time zone offset. It's more commonly written as -04:00 (Invert the sign, divide by 60).
The US Eastern Time Zone is comprised of both Eastern Standard Time, which has the offset of -05:00 and Eastern Daylight Time, which has the offset of -04:00.
So it is not at all accurate to say US/Eastern = 240. Please read the timezone tag wiki, especially the section titled "Time Zone != Offset".
Now you did ask for the current offset, which is possible. If you supply a date+time reference, then you can resolve this.
For the local time zone of the computer where the javascript code is executing, this is built in with .getTimeZoneOffset() from any instance of a Date object.
But if you want it for a specific time zone, then you will need to use one of the libraries I listed here.

It has become possible nowaday with Intl API:
The implementation of Intl is based on icu4c. If you dig the source code, you'll find that timezone name differs per locale, for example:
for (const locale of ["ja", "en", "fr"]) {
const timeZoneName = Intl.DateTimeFormat(locale, {
timeZoneName: "short",
timeZone: "Asia/Tokyo",
})
.formatToParts()
.find((i) => i.type === "timeZoneName").value;
console.log(timeZoneName);
}
Fortunately, there is a locale, Interlingua (the langauge tag is ia), which uses the same pattern (ex. GMT+11:00) for timezone names.
The snippet below can meed your need:
const getOffset = (timeZone) => {
const timeZoneName = Intl.DateTimeFormat("ia", {
timeZoneName: "short",
timeZone,
})
.formatToParts()
.find((i) => i.type === "timeZoneName").value;
const offset = timeZoneName.slice(3);
if (!offset) return 0;
const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
if (!matchData) throw `cannot parse timezone name: ${timeZoneName}`;
const [, sign, hour, minute] = matchData;
let result = parseInt(hour) * 60;
if (sign === "+") result *= -1;
if (minute) result += parseInt(minute);
return result;
};
console.log(getOffset("US/Eastern")); // 240
console.log(getOffset("Atlantic/Reykjavik")); // 0
console.log(getOffset("Asia/Tokyo")); // -540
This way can be a little tricky but it works well in my production project. I hope it helps you too :)
Update
Many thanks to Bort for pointing out the typo. I have corrected the snippet.

Following function can be used to return the UTC offset given a timezone:
const getTimezoneOffset = (timeZone, date = new Date()) => {
const tz = date.toLocaleString("en", {timeZone, timeStyle: "long"}).split(" ").slice(-1)[0];
const dateString = date.toString();
const offset = Date.parse(`${dateString} UTC`) - Date.parse(`${dateString} ${tz}`);
// return UTC offset in millis
return offset;
}
It can be used like:
const offset = getTimezoneOffset("Europe/London");
console.log(offset);
// expected output => 3600000

You can do this using moment.js
moment.tz('timezone name').utcOffset()
Although this involves using moment-timezone.js

The answer of #ranjan_purbey results in NaN for me and the answer of #Weihang Jian throws an exception in Chrome (but works in Firefox).
Therefore, based on all the answers I came up with the following function which is basically a combination of both answers working together successfully for me:
function getTimeZoneOffset(timeZone) {
const date = new Date().toLocaleString('en', {timeZone, timeZoneName: 'short'}).split(' ');
const timeZoneName = date[date.length - 1];
const offset = timeZoneName.slice(3);
if (!offset) {
return 0;
}
const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
if (!matchData) {
throw new Error(`Cannot parse timezone name: ${timeZoneName}`);
}
const [, sign, hour, minute] = matchData;
let result = parseInt(hour, 10) * 60;
if (sign === '+') {
result *= -1;
}
if (minute) {
result += parseInt(minute, 10);
}
return result;
}

Related

How to use startOfDay from date-fns with timezones?

I try to replace momentjs with date-fns
but I am struggling with a very simple thing:
I need to calculate startOfDay, end of day and addDays for the dates that I have got in timestamps and according to the giving timezone.
date = 1492437600; // Monday April 17, 2017 12:00:00 (pm) in time zone America/Noronha
timeZone = 'America/Noronha';
_startOfDay = utcToZonedTime(startOfDay(date*1000), timeZone).getTime()/1000;
and I have got the result for the _startOfDay = 1492365600 that is Sunday April 16, 2017 16:00:00 (pm) in time zone America/Noronha
What I am doing wrong?
thanks in advance
Note: See the bottom of this answer for the best solution
Old Answer:
I see this question is 11 months old (as of writing) but thought I'd answer it as I hit the same problem, and others may come here in the future with the same question.
The date-fns library doesn't have timezone support, so you need to also use the date-fns-tz library. Import the getTimezoneOffset function from date-fns-tz and use to calculate the offset between the local (browser) timezone and the timezone you wish to calculate end of day for (i.e. America/Noronha). Note that the date-fns "endOf" functions use the local/browser timezone.
E.g.
import { endOfDay } from 'date-fns';
import { getTimezoneOffset } from 'date-fns-tz/esm';
const MILLISECS_IN_DAY = 86400000;
const localTz = Intl.DateTimeFormat().resolvedOptions().timeZone; // Browser Timezone
const tzOffset = getTimezoneOffset('America/Noronha') - getTimezoneOffset(localTz);
// Have to cater for negative offsets
const tzOffsetEOD = (tzOffset < 0) ? (MILLISECS_IN_DAY + tzOffset) : tzOffset;
let testDate = new Date();
let eodInTimezone = endOfDay(testDate).getTime() - tzOffsetEOD; // in millisecs
// Have to project forward a day if the result is in the past
if (eodInTimezone < testDate.getTime()) eodInTimezone += MILLISECS_IN_DAY;
Someone may be able to come up with a more elegant solution to this problem. If I do I'll post back here.
New Answer:
This solution works best for all "End Of" date-fns functions:
import { endOfDay, endOfWeek, endOfMonth, endOfYear } from 'date-fns';
import { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz/esm';
const calcZonedDate = (date, tz, fn, options = null) => {
const inputZoned = utcToZonedTime(date, tz);
const fnZoned = (options) ? fn(inputZoned, options) : fn(inputZoned);
return zonedTimeToUtc(fnZoned, tz);
}
const getZonedEndOfDay = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfDay);
}
const getZonedEndOfWeek = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfWeek, { weekStartsOn: 1 });
}
const getZonedEndOfMonth = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfMonth);
}
const getZonedEndOfYear = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfYear);
}
// Example Usage
let endOfDayZoned = getZonedEndOfDay(new Date(), 'America/Noronha');
Hope this helps.

Get Offset of the other Location in Javascript

I am in Asia and I want to calculate the offset of Australia. I know how to calculate the value of the offset the code is written below:
var timezone_offset = new Date().getTimezoneOffset();
But how to calculate it for the other locations? Anyone can guide me??
While this can be done in a short function, it would be best to use a library as there are many quirks to overcome. The offset can be determined using the timezone options of toLocaleString or Intl.DateTimeFormat.
However, if the language used for formatting matches the language of the location, it returns the timezone abbreviation instead of the offset. To deal with that, the following function first uses English and if that returns the abbreviation rather than an offset, it uses French. English offsets start with GMT, French offsets start with UTC. Where the offset is +0, they return just "GMT" or "UTC".
It's been tested with all IANA locations listed by wikipedia and seems to work for all of them but it should be tested more widely. Also, there should be feature tests before attempting to run it (i.e. support for Int.DateTimeFormat constructor, formatToParts method and the timeZoneName option).
// Return offset on date for loc in ±H[:mm] format. Minutes only included if not zero
function getTimezoneOffset(date, loc) {
// Try English to get offset. If get abbreviation, use French
let offset;
['en','fr'].some(lang => {
// Get parts - can't get just timeZoneName, must get one other part at least
let parts = new Intl.DateTimeFormat(lang, {
minute: 'numeric',
timeZone: loc,
timeZoneName:'short'
}).formatToParts(date);
// Get offset from parts
let tzName = parts.filter(part => part.type == 'timeZoneName' && part.value);
// timeZoneName starting with GMT or UTC is offset - keep and stop looping
// Otherwise it's an abbreviation, keep looping
if (/^(GMT|UTC)/.test(tzName[0].value)) {
offset = tzName[0].value.replace(/GMT|UTC/,'') || '+0';
return true;
}
});
// Format offset as ±HH:mm
// Normalise minus sign as ASCII minus (charCode 45)
let sign = offset[0] == '\x2b'? '\x2b' : '\x2d';
let [h, m] = offset.substring(1).split(':');
return sign + h.padStart(2, '0') + ':' + (m || '00');
}
let d = new Date();
console.log('Current offset for following locations:');
['Australia/Yancowinna',
'Australia/Lord_Howe',
'Australia/Canberra',
'Pacific/Honolulu',
'Europe/London',
'Canada/Eastern'
].forEach( loc =>
console.log(loc + ': ' + getTimezoneOffset(d, loc))
);
I don't suggest you use this function, it's really to show how messy getting the offset for a specific location can be.
Note that Australia has a number of offsets and some places observe daylight saving and others don't.
The accepted answer is correct, but if you are fine with some of the timezones to appear without the percise offset, a shorter way that doesn't require string parsing / manipulation will be:
// Return offset on date for loc in ±H[:mm] format.
function getTimezoneOffset(date, loc) {
return new Intl.DateTimeFormat('en-US', { timeZone: loc, timeZoneName: "shortOffset" })
.formatToParts(date)
.filter(e => e.type === "timeZoneName")[0].value
}
let d = new Date();
console.log('Current offset for following locations:');
['Australia/Yancowinna',
'Australia/Lord_Howe',
'Australia/Canberra',
'Pacific/Honolulu',
'Europe/London',
'Canada/Eastern',
'America/Los_Angeles',
'Asia/Kolkata'
].forEach(loc =>
console.log(loc + ': ' + getTimezoneOffset(d, loc))
);
You can see the the options for the timezone name format here [1]:
timeZoneName - The localized representation of the time zone name.
Possible values are:
"long" Long localized form (e.g., Pacific Standard Time, Nordamerikanische Westküsten-Normalzeit)
"short" Short localized form (e.g.: PST, GMT-8)
"shortOffset" Short localized GMT format (e.g., GMT-8)
"longOffset" Long localized GMT format (e.g., GMT-0800)
"shortGeneric" Short generic non-location format (e.g.: PT, Los Angeles Zeit).
"longGeneric" Long generic non-location format (e.g.: Pacific Time, Nordamerikanische Westküstenzeit)
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#syntax:~:text=timeZoneName,Nordamerikanische%20Westk%C3%BCstenzeit)

How to reposition datetime into the current timezone when converting an ISO 8601 datetime string to a **Date** object?

Let's say we're in London at midnight on 2020-01-01 and make an entry into an app that stores the datetime as an ISO-8601 string like this.
2020-01-01T00:00:00-00:00
Later, I am in Los Angeles and want to view this date on a chart that requires a javascript date object.
Getting the localized date object is easy.
const iso8601Date = '2020-01-01T00:00:00+00:00';
const theDate = new Date(iso8601Date);
console.log(typeOf(theDate)); // date
console.log(theDate); // Tue Dec 31 2019 16:00:00 GMT-0800 (PST)
But, sometimes we want to "ignore" the timezone offset and analyze the data as if it happened in the current timezone.
This is the result I'm looking for but don't know how to accomplish.
const iso8601Date = '2020-01-01T00:00:00+00:00';
const theRepositionedDate = someMagic(iso8601Date);
console.log(typeOf(theRepositionedDate)); // date
console.log(theRepositionedDate); // Wed Jan 01 2020 00:00:00 GMT-0800 (PST)
How do you reposition the date and return a date object?
/* Helper function
Returns the object type
https://stackoverflow.com/a/28475133/25197
typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
*/
function typeOf(obj) {
return {}.toString
.call(obj)
.split(' ')[1]
.slice(0, -1)
.toLowerCase();
}
This is really a duplicate of Why does Date.parse give incorrect results?, but that may not seem apparent at first glance.
The first rule of parsing timestamps is "do not use the built–in parser", even for the 2 or 3 formats supported by ECMA-262.
To reliably parse a timestamp, you must know the format. Built–in parsers try and work it out, so there are differences between them that may well produce unexpected results. It just happens that '2020-01-01T00:00:00+00:00' is probably the only supported format that is actually reliably parsed. But it does differ slightly from strict ISO 8601, and different browsers differ in how strictly they apply the ECMAScript parsing rules so again, very easy to get wrong.
You can convert it to a "local" timestamp by just trimming the offset information, i.e. '2020-01-01T00:00:00', however Safari at least gets it wrong and treats it as UTC anyway. ECMAScrip itself is inconsistent with ISO 8601 by treating date–only forms of ISO 8601 as UTC (i.e. '2020-01-01' as UTC when ISO 8601 says to treat it as local).
So just write your own parser or use a library, there are plenty to choose from. If you're only looking for parsing and formatting, there are some that are less than 2k minified (and there are examples on SO).
Writing your own is not that challenging if you just want to support straight forward ISO 8601 like formats, e.g.
// Parse ISO 8601 timestamps in YYYY-MM-DDTHH:mm:ss±HH:mm format
// Optional "T" date time separator and
// Optional ":" offset hour minute separator
function parseIso(s, local) {
let offset = (s.match(/[+-]\d\d:?\d\d$/) || [])[0];
let b = s.split(/\D/g);
// By default create a "local" date
let d = new Date(
b[0],
b[1]-1,
b[2] || 1,
b[3] || 0,
b[4] || 0,
b[5] || 0
);
// Use offset if present and not told to ignore it
if (offset && !local){
let sign = /^\+/.test(offset)? 1 : -1;
let [h, m] = offset.match(/\d\d/g);
d.setMinutes(d.getMinutes() - sign * (h*60 + m*1) - d.getTimezoneOffset());
}
return d;
}
// Samples
['2020-01-01T00:00:00+00:00', // UTC, ISO 8601 standard
'2020-01-01 00:00:00+05:30', // IST, missing T
'2020-01-01T00:00:00-0400', // US EST, missing T and :
'2020-01-01 00:00:00', // No timezone, local always
'2020-01-01' // Date-only as local (differs from ECMA-262)
].forEach(s => {
console.log(s);
console.log('Using offset\n' + parseIso(s).toString());
console.log('Ignoring offset\n' + parseIso(s, true).toString());
});
Building off of #RobG's answer I was able to speed this one up a little by using a single regex. Posting here for posterity.
const isoToDate = (iso8601, ignoreTimezone = false) => {
// Differences from default `new Date()` are...
// - Returns a local datetime for all without-timezone inputs, including date-only strings.
// - ignoreTimezone processes datetimes-with-timezones as if they are without-timezones.
// - Accurate across all mobile browsers. https://stackoverflow.com/a/61242262/25197
const dateTimeParts = iso8601.match(
/(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d{0,7}))?(?:([+-])(\d{2}):(\d{2}))?)?/,
);
// Create a "localized" Date by always specifying a time. If you create a date without specifying
// time a date set at midnight in UTC Zulu is returned. https://www.diigo.com/0hc3eb
const date = new Date(
dateTimeParts[1], // year
dateTimeParts[2] - 1, // month (0-indexed)
dateTimeParts[3] || 1, // day
dateTimeParts[4] || 0, // hours
dateTimeParts[5] || 0, // minutes
dateTimeParts[6] || 0, // seconds
dateTimeParts[7] || 0, // milliseconds
);
const sign = dateTimeParts[8];
if (sign && ignoreTimezone === false) {
const direction = sign === '+' ? 1 : -1;
const hoursOffset = dateTimeParts[9] || 0;
const minutesOffset = dateTimeParts[10] || 0;
const offset = direction * (hoursOffset * 60 + minutesOffset * 1);
date.setMinutes(date.getMinutes() - offset - date.getTimezoneOffset());
}
return date;
};
The key difference is a single regex that returns all the matching groups at once.
Here's a regex101 with some examples of it matching/grouping.
It's about double the speed of the #RobG's awesome accepted answer and 4-6x faster than moment.js and date-fns packages. 👍
const createDate = (isoDate) => {
isoDate = new Date(isoDate)
return new Date(Date.UTC(
isoDate.getUTCFullYear(),
isoDate.getUTCMonth(),
isoDate.getUTCDate(),
isoDate.getUTCMinutes(),
isoDate.getUTCSeconds(),
isoDate.getUTCMilliseconds()
));
}
const iso8601Date = '2020-01-01T00:00:00+00:00';
const theRepositionedDate = createDate(iso8601Date);
console.log(theRepositionedDate instanceof Date); // true
console.log(theRepositionedDate);
But, sometimes we want to "ignore" the timezone offset and analyze the data as if it happened in the current timezone.
Ok, then ignore it.
const iso8601Date = '2020-01-01T00:00:00+00:00';
const theDate = new Date(iso8601Date.substring(0, 19));
This works because you're creating a Date object from 2020-01-01T00:00:00 - an ISO 8601 date-time without offset.
ECMAScript section 20.3.1.15 - Date Time String Format says:
When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.

MomentJS and JS Date objects not referring to the same hour

I've got a server instance (NodeJS) that receives a set of objects, and schedules them for sending push notifications to users.
Some of these objects, are periodic, and this periodicity is handled by a string like this:
90=>Mon&Tue&Thu=>16:00
Which is read as:
offset_minutes=>days_of_the_week=>initial_hour
Then, what I do is to check whether the current day matches one of the given days in the string, and then, modify the date to the given hour in the "initial_hour", and finally, substract the "offset_minutes" amount of minutes from the Date object.
Seems straightforward until now, right? Well, not that much. Let's first see the code:
const isToday = weekDays.split("&")
.map(a => {
switch (a) {
case 'Mon': return 1;
case 'Tue': return 2;
case 'Wed': return 3;
case 'Thu': return 4;
case 'Fri': return 5;
case 'Sat': return 6;
case 'Sun': return 7;
}
})
.some(v => v == currentDay);
if (isToday) {
let finalDate = moment(today)
.set("hour", Number(hour))
.set("minute", Number(mins));
if (offset) {
finalDate.subtract('minutes', Number(offset));
}
return finalDate.toDate();
Everything works well, until I do the MomentJS transformations. When I output a Date object with the ".toDate()" method, this object is always set to 2 hours before the expected time. But if I use the .toISOString() method, I get the proper time for all the occurrencies.
I guess that something is wrong with my Date objects, setting them up at a different timezone than the one I have. A couple of examples:
For the string 90=>Mon&Tue&Thu=>16:00 I get the Date object: 2019-10-14T14:00:11.852Z
For the string 30=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30 I get the Date object: 2019-10-14T16:30:11.866Z
I would like to know what's the explanation for such a behavior, and if I can do something to change it so the normal Javascript Date object points to the same hour than my momentjs object, or the .toISOString() output.
Thank you!
The posted code is incomplete and doesn't demonstrate the issue described.
I've reimplemented the code without moment.js as best I can and simplified it. It seems to work fine:
function parseThing(s) {
// Parse input string
let b = s.split('=>');
let offset = +b[0];
let days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
let weekDays = b[1].split('&').map(day => days.indexOf(day));
let [hr, min] = b[2].split(':');
// Get a date for today
let date = new Date();
// If today included, return an adjusted date
if (weekDays.includes(date.getDay())) {
date.setHours(hr, min, 0, 0);
if (offset) {
date.setMinutes(date.getMinutes()+ Number(offset));
}
return date;
}
// If today isn't included, return null
return null;
}
let s0 = '90=>Mon&Tue&Thu=>16:00';
let s1 = '0=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30';
console.log(parseThing(s0).toString());
console.log(parseThing(s1).toString());
Where the local day is one of those in the string (Mon, Tue, Thu) it returns a Date equivalent to a local time of 17:30, which is 90 minutes offset from 16:00, which seems to be correct.
PS I've changed Sunday to 0 as I can't see any rationale for it to be 7. Also seconds and milliseconds are zeroed too.

get timezone offset of another timezone in javascript without using Strings

I want to calculate the offset from 'users time' to 'WET/WEST'.
I get the users offset with new Date().getTimezoneOffset().
But how do I get the offset for WET/WEST So that I can calcluate the combined offset of both?
For example, if the user is in central europe time (CET/CEST), in winter the combined offset would be -60 (CET) + 0 (WET) = -60. In summer, it would be -120 (CEST) + 60 (WEST) = -60. In this case it is always -60 but the user could also have a timezone without DST.
Is this possible without format it to a string and read out the new timezone from that string?
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 = new Date();
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.
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
function getTimezoneOffset(dt, timezone) {
let getItem = function(format) {
format.timeZone = timezone;
return parseInt(dt.toLocaleString(
'en-US', format));
};
let adjDate = new Date(
getItem({year: 'numeric'}),
getItem({month: 'numeric'}) - 1, // months are zero based
getItem({day: 'numeric'}),
getItem({hour: 'numeric',hour12: false}),
getItem({minute: 'numeric'}));
let noSecs = new Date(dt.getTime());
noSecs.setSeconds(0, 0);
let diff = Math.round((adjDate.getTime() - noSecs.getTime()) / 60000);
return dt.getTimezoneOffset() - diff;
}
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:
function getTimezoneOffsetFrom(otherTimezone) {
if (otherTimezone === void 0) { otherTimezone = "Europe/Amsterdam"; }
var date = new Date();
function objFromStr(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.
function getTimezoneOffset(atTime, timeZone) {
const localizedTime = new Date(atTime.toLocaleString("en-US", {timeZone}));
const utcTime = new Date(atTime.toLocaleString("en-US", {timeZone: "UTC"}));
return (localizedTime.getTime() - utcTime.getTime()) / (60*60*1000);
}
// returns -6 or -7 depending on the time of year
console.log(getTimezoneOffset(new Date(), "America/Denver"));
// returns -5 or -6 depending on the time of year
console.log(getTimezoneOffset(new Date(), "America/Chicago"));

Categories

Resources