0

I have to publish an online program for an international conference. Rather than just showing the date and time of each event according to our timezone (UTC+11), I want the page to display them according to the user's timezone. When the page loads it should show what the server thinks the user's timezone is, but give the user the opportunity to override it, using a dropdown.

I have managed to get this to work:

<script>
function convertTZ(date, tzString) {
    return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {timeZone: tzString}));   
}
</script>

<body onload = "document.getElementById('datetime').innerHTML = convertTZ('2021/01/09 11:00:00 +1100','Europe/Paris')">
<p id="datetime"></p>
</body>

But how to I get the user’s timezone string and allow the user to override this? I also will need to extract just the date + time without the timezone info (eg "GMT+1100 (Australian Eastern Daylight Time)") but hopefully I can work that out myself.

(I am very much a JavaScript beginner.)

Any help would be greatly appreciated, particularly if someone knows of something that already exists, which I could adapt. Thanks.

1 Answers1

0

A few things:

  • You should specify the time of the event in ISO 8601 format: 2021-01-09T11:00:00+11:00.

    • Or rather, more accurately stated, it should be in the ECMAScript Date Time String Format, such that it is understood unambiguously by all implementations.
      2021-01-09T11:00:00+11:00 is compliant with both. 2021/01/09 11:00:00 +1100 is not compliant, and thus would be considered non-standard, implementation-specific, and possibly fail in some browsers.
  • To use the user's time zone, do not specify a timeZone option to toLocaleString. The default is the user's time zone already.

  • You should also not supply a locale (en-US), as the formatting of toLocaleString will use the user's locale settings by default. If you want to supply other options, you can pass undefined for the locale to keep the user's default locale intact.

  • You might want to include the timeZoneName option (either long or short) to display a human-readable time zone description in the output. That will make it clearer for your user to understand the context of the information being displayed.

In the end, you probably want something similar to:

function loadDateTime() {
  const eventTime = new Date("2021-01-09T11:00:00+11:00");
  const display = eventTime.toLocaleString(undefined, { timeZoneName: 'long' });
  document.getElementById('datetime').innerHTML = display;
}
<body onload="loadDateTime()">
  <p id="datetime"></p>
</body>

For me, it outputs: 1/8/2021, 4:00:00 PM Pacific Standard Time. You will get a different result depending on your locale and time zone.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Thanks. Interestingly for me, it outputs: `2021/01/09 11:00:00`. No comma and no time zone. – JonathanCooper Dec 30 '20 at 01:37
  • If I switch my time zone to Sydney, I get `"1/9/2021, 11:00:00 AM Australian Eastern Daylight Time"` from the above snippet. I'm running Google Chrome 87 (latest) on Windows 10, from the USA (which affects the date and time formats). Indeed, you may get different results depending on the level of the browser's support of Intl. – Matt Johnson-Pint Dec 30 '20 at 19:38
  • Sorry, Matt. I was completely wrong with that last comment. What I _thought_ was output was text I'd forgotten to remove. (face-slap!) What I actually get is `1/9/2021, 11:00:00 AM Australian Eastern Daylight Time` (same as you). But in Australia we have D/M/Y format, so why does it output the US-style M/D/Y? Is there any way to make it respect the local format, or failing that, can the function be changed to make it always output Y-M-D? Thanks in anticipation. – JonathanCooper Dec 31 '20 at 13:18
  • `undefined` in the first argument to `toLocaleString` tells the browser to use the user's locale settings. This can be done in browser (ex, in Chrome there's a *Languages* setting at `chrome://settings/languages` that is *US English* for me). Depending on browser it can also be from the format settings from the underlying operating system (such as in Windows 10, the *Region* settings under *Time & Language*). If you wanted to override the locale, you could pass `'en-AU'` (for example) instead of `undefined`, but I recommend against that unless you can guarantee all users are from Australia. – Matt Johnson-Pint Jan 04 '21 at 18:20
  • You can see your own locale setting with `Intl.DateTimeFormat().resolvedOptions().locale` on the debug console. Whatever that is will have the same effect as `undefined`. – Matt Johnson-Pint Jan 04 '21 at 18:24