'How to pass in dynamic value into toLocaleTimeString

So I'd like to pass in a dynamic value into toLocaleTimeString. The way the time is formatted is going to change based on the user location. For example time for a user in the UK should be something like 18:00:00, while for someone in America it would be 6:00:00 PM.

The only problem I'm having is doing a dynamic mapping of timezone to which locale to pass in (i.e. "en-GB", "en-US", etc). How do I do this?

I'm using momenttimezone and tzlookup to get the user timezone:

let timezone = tzlookup(userLatitude, userLongitude)

var date = new Date()
var localHour = date.toLocaleTimeString("xx-XX") // How do I dynamically set xx-XX to what it's supposed to be based on the user location?

Any help is much appreciated!



Solution 1:[1]

Time zones and locales are two orthogonal concepts. You should not make any assumptions that bind them together. In many cases, they can be quite different. For example, if I am an English speaking American visiting Japan, my device will likely have a time zone of Asia/Tokyo and a locale of en-US.

As for toLocaleTimeString (and toLocaleDateString, toLocaleString, Intl.DateTimeFormat, etc.) the default value of undefined will automatically use the user's current locale.

In other words:

// this uses the current locale and current time zone
date.toLocaleString()

// this uses a specific locale and current time zone
date.toLocaleString('en-US')

// this uses the current locale and a specific time zone
date.toLocaleString(undefined, {timeZone: 'Asia/Tokyo'})

// this uses a specific locale and a specific time zone
date.toLocaleString('en-US', {timeZone: 'Asia/Tokyo'})

In your example, if you want to display a time in the UK time zone (the mainland, not a dependency or overseas territory), then you can use the time zone Europe/London. Your call to tzlookup should be returning that. You should not choose a locale. Let the user's browser set that according to their preferences.

const timezone = tzlookup(userLatitude, userLongitude)

const date = new Date()
const localHour = date.toLocaleTimeString(undefined, {timeZone: timezone}) 

You should not need moment or moment-timezone for this operation.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Matt Johnson-Pint