0

I see the lovely methods to determine local DSTedness. However, I have to react according to the time in Chicago (or any fixed HQ location.) So, finding out what my current DTC hour is doesn't help if I can't know whether I'm looking for 15 or 16 (10 AM Central dependent on daylight savings time.) Why am I not surprised that the Date.UTC doesn't have an argument for offset?

mardukes
  • 93
  • 1
  • 7
  • 1
    Unfortunately the Date object has been utterly neglected by TC39. The inclusion of ECMA-402 Internationalisation API has not helped much, and in the case of Dates, made things worse. Likely there are web APIs that will provide the information you require with much less effort that messing about with the built–in Date and related methods. – RobG Feb 20 '20 at 22:31
  • Does this answer your question? [Convert date to another timezone in JavaScript](https://stackoverflow.com/questions/10087819/convert-date-to-another-timezone-in-javascript) – codeMonkey Feb 20 '20 at 23:14
  • @codeMonkey—the accepted answer there depends on the vagaries of the built–in parser, which is not a good idea. – RobG Feb 20 '20 at 23:20
  • You've inspired me! I'm working in Dynamics and asked myself, what about Bing Maps? A little scripting, a longitude/latitude pair and, voila', the current UTC offset in the Central timezone! – mardukes Feb 21 '20 at 13:37
  • `var url = "https://dev.virtualearth.net/REST/v1/TimeZone/" + point + "?datetime=" + datetime_utc + "&key=" + BingMapsAPIKey;` – mardukes Feb 21 '20 at 13:46
  • @mardukes—Google has a [similar API](https://developers.google.com/maps/documentation/timezone/start), however you can't always get the user's geolocation, nor might you know the coordinates of the place you want the timezone offset for. – RobG Feb 22 '20 at 06:18

1 Answers1

0

To determine the timezone offset for a particular place, you can use toLocaleString with an IANA representative location. Unfortunately that only gets you a timestamp, so you'll have to parse that to work out the timezone offset, e.g.

function getCurrentOffset(loc) {
  // Helper
  let z = n => (n<10? '0':'')+n;
  // Current date, zero minutes
  let now = new Date();
  now.setSeconds(0, 0);
  // Options for toLocaleString, use set lang so know format returned
  let lang = 'en-GB';
  let opts = {
    timeZone:loc,
    hour12: false,
    hour: '2-digit',
    minute: '2-digit',
    day: '2-digit',
    month: '2-digit',
    year: 'numeric'
  };
  // Get timestamp for loc
  let s = now.toLocaleString(lang, opts);
  // Parse as UTC and get diff from now
  let [d,m,y,h,min] = s.split(/\D+/);
  let diffMin = (now - Date.UTC(y,m-1,d,h,min))/60000;
  // Convert diffMin to +/-HH:MM
  let sign = diffMin > 0? '-':'+';
  diffMin = Math.abs(diffMin);
  let diffHr = diffMin/60 | 0;
  return sign + z(diffHr) + ':' + z(diffMin%60);
}

[
  'Europe/London','America/Denver','Australia/Sydney','Africa/Luanda',
  'America/Argentina/Salta','Australia/Lord_Howe','Pacific/Tongatapu'
].forEach(
  loc => console.log(loc + ': ' + getCurrentOffset(loc))
);

This is limited by the host implementation's support for IANA representative locations and obscurity of the locations being used.

If you just want to get the current time in a particular location, then toLocaleString can help, however you need to be wary of patchy support.

let now = new Date();
let opts = {hour:'2-digit', minute:'2-digit'};
let lang = 'en-GB';

['Europe/London','America/Denver','Australia/Sydney',
 'Africa/Luanda','America/Argentina/Salta',
 'Australia/Lord_Howe','Pacific/Tongatapu'
].forEach(loc => {
  opts.timeZone = loc;
  console.log(loc + ': ' + now.toLocaleString(lang, opts))
});
RobG
  • 142,382
  • 31
  • 172
  • 209