27

I found many solution that gives Timezone name from offset value. But I have Timezone name and I want offset value for that. I tried setTimezone('Asia/Kolkata'), but I think their is no method like setTimezone.

example:

Asia/Kolkata should give me -330 ( offset )
Hardik Sondagar
  • 4,347
  • 3
  • 28
  • 48
  • have you tried http://momentjs.com/ ? – Anto Subash Jan 24 '14 at 08:20
  • Let me see if i've understood your siutation. You have a timezeon A and you want to get the time difference between other timezone B. My questión is... your variable are the two timezones, hence both time zone will be changer often? or only one of this timezone may change, for example there is a client with a timezone and you just one to know the time difference from the client to your server? – user688877 Jan 24 '14 at 11:40
  • only one timezone will change...Server's timezone is fix it's UTC 0. When client timezone is Asia/Kolkata in that case I want offset of that timezone (means -330 minutes ). – Hardik Sondagar Jan 25 '14 at 09:49

4 Answers4

24

This has got the be the easiest way to accomplish this task with modern JavaScript.

Note: Keep in mind that the offset is dependent on whether Daylight Savings Time (DST) is active.

/* @return A timezone offset in minutes */
const getOffset = (timeZone = 'UTC', date = new Date()) => {
  const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));
  const tzDate = new Date(date.toLocaleString('en-US', { timeZone }));
  return (tzDate.getTime() - utcDate.getTime()) / 6e4;
}

console.log(`No arguments: ${getOffset()}`); // 0

{
  console.log('! Test Case #1 >> Now');
  console.log(`Asia/Colombo     : ${getOffset('Asia/Colombo')}`);     //  330
  console.log(`America/New_York : ${getOffset('America/New_York')}`); // -240
}

{
  console.log('! Test Case #2 >> DST : off');
  const date = new Date(2021, 0, 1);
  console.log(`Asia/Colombo     : ${getOffset('Asia/Colombo', date)}`);     //  330
  console.log(`America/New_York : ${getOffset('America/New_York', date)}`); // -300
}

{
  console.log('! Test Case #3 >> DST : on');
  const date = new Date(2021, 5, 1);
  console.log(`Asia/Colombo     : ${getOffset('Asia/Colombo', date)}`);     //  330
  console.log(`America/New_York : ${getOffset('America/New_York', date)}`); // -240
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • I have 2 suggestions: 1. use `Date.parse()` instead of `new Date()`. . 2. Add the string `' Z'` to the output of `toLocaleString()` and the function gives different offsets depending on if DST is active or not: `Date.parse(date.toLocaleString(systemTimeZone, { timeZone }) + ' Z')` – some Jul 22 '23 at 14:28
11

I came across this same issue, and this is the solution I came up with, if you can get an IANA tz database name like the one you mentioned:

const myTimezoneName = "Asia/Colombo";
 
// Generating the formatted text
// Setting the timeZoneName to longOffset will convert PDT to GMT-07:00
const options = {timeZone: myTimezoneName, timeZoneName: "longOffset"};
const dateText = Intl.DateTimeFormat([], options).format(new Date);
 
// Scraping the numbers we want from the text
// The default value '+0' is needed when the timezone is missing the number part. Ex. Africa/Bamako --> GMT
let timezoneString = dateText.split(" ")[1].slice(3) || '+0';

// Getting the offset
let timezoneOffset = parseInt(timezoneString.split(':')[0])*60;

// Checking for a minutes offset and adding if appropriate
if (timezoneString.includes(":")) {
   timezoneOffset = timezoneOffset + parseInt(timezoneString.split(':')[1]);
}

It's not a very nice solution, but it does the job without importing anything. It relies on the output format of the Intl.DateTimeFormat being consistent, which it should be, but that's a potential caveat.

asiby
  • 3,229
  • 29
  • 32
Baptiste Higgs
  • 111
  • 1
  • 5
  • 1
    Thank you! After much searching, I finally found my answer here. Much appreciated. – Armando Jul 01 '21 at 12:48
  • Note, it won't always work because in "short" format some timezones are represented by their name like "PST" rather than their offset. The better approach would be to print timezone in "shortOffset" format, but this option is not supported in Node.js. – Alexander Korostin Jan 16 '22 at 21:43
  • Node.js now supports the "shortOffset" and "longOffset" options for timeZoneName. – diachedelic Jun 24 '22 at 02:22
  • 1
    Good answer. However, it needs a tweak. The line that scaps the number from the text do not work for timezones that resolve to GMT instead of GMT+0. I will update the answer to add a fix. – asiby Jun 24 '22 at 15:19
  • @AlexanderKorostin, using "longOffset" as timezone format will solve that. I have edited the answer again to address that. – asiby Jun 24 '22 at 16:41
5

You can't get it by name alone. You would also need to know the specific time. Asia/Kolkata may be fixed to a single offset, but many time zones alternate between standard time and daylight saving time, so you can't just get the offset, you can only get an offset.

For how to do it in JavaScript, see this answer.

Community
  • 1
  • 1
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
3

Using countries and timezones npm package:

import {getTimezone} from 'countries-and-timezones';
const australianTimezone = 'Australia/Melbourne';
console.log(getTimezone(australianTimezone));

Prints to the console:

{
  name: 'Australia/Melbourne',
  country: 'AU',
  utcOffset: 600,
  utcOffsetStr: '+10:00',
  dstOffset: 660,
  dstOffsetStr: '+11:00',
  aliasOf: null
}

From there, you can use the utcOffset or dstOffset depending on if it is daylight savings time.

Nathan Dullea
  • 343
  • 2
  • 6
  • 13