Sudhakar B
Sudhakar B

Reputation: 1563

Javascript Intl - How to get all timezones with abbrivation and offset

Any standard method in javascript which can get timezone abbreviation and offset using Intl?

Intl.supportedValuesOf('timeZone') gets all timezones. How can I get timezone abbreviation and offset along with timezone. For eg., I need to get PDT / PST abbreviation, offset UTC−07:00 for the timezone America/Los_Angeles

Upvotes: 3

Views: 3864

Answers (2)

Terry Lennox
Terry Lennox

Reputation: 30685

I'd suggest using the formatToParts() function, you can get the abbreviation and offset using the 'short' and 'longOffset' components.

function getAbbreviation(timeZone) {
    return getFormattedElement(timeZone, 'timeZoneName', 'short')
}

function getOffset(timeZone) {
    return getFormattedElement(timeZone, 'timeZoneName', 'longOffset')
}

function getFormattedElement(timeZone, name, value) {
    return (new Intl.DateTimeFormat('en', {
        [name]: value,
        timeZone 
    }).formatToParts().find(el => el.type === name) || {}).value;
}

console.log('Abbreviation:', getAbbreviation('America/Los_Angeles'));
console.log('Offset:', getOffset('America/Los_Angeles'));

Note that this gives offsets in the format GMT(+|-)..., not UTC(+|-)... — this can be easily fixed by using getOffset(timeZone).replace('GMT', 'UTC').

In addition, Intl.DateTimeFormat#formatToParts uses the current system time as a default if no parameter is supplied, which means the offset is scoped to the current date (i.e. taking daylight-savings into account). If the offset as of a different date is required, you could allow supplying additional parameters:

function getFormattedElement(timeZone, name, value, ...dateParams) {
    return (new Intl.DateTimeFormat('en', {
        [name]: value,
        timeZone,
    }).formatToParts(new Date(...dateParams)).find(el => el.type === name) || {}).value;
}

for (const year of [2022, 2023]) {
    console.log(`Europe/London, Mar 26, ${year}:`, getFormattedElement('Europe/London', 'timeZoneName', 'longOffset', `${year}-03-26T12:00:00Z`));
}


Also worth looking at tzdb, this maintains a list of detailed timezone information, including offset, abbreviation etc.

.as-console-wrapper { max-height: 100% !important; }
<script type="module">

import { getTimeZones } from 'https://cdn.skypack.dev/@vvo/tzdb'

const timeZones = getTimeZones();

function minutesToHHMM(minutes) {
    const hours = Math.floor(minutes / 60);
    const mins = Math.abs(minutes % 60);
    return (hours < 0 ? '-': '+') + (Math.abs(hours) + '').padStart(2, '0') + ':' + (mins + '').padStart(2, '0')
}

function getTimezoneDetails(tz) {
    const currentOffsetMinutes = tz.currentTimeOffsetInMinutes;
    const currentOffset = 'UTC' + minutesToHHMM(currentOffsetMinutes);
    return { name: tz.name, currentOffsetMinutes, currentOffset, abbreviation: tz.abbreviation }
}

console.log(timeZones.map(getTimezoneDetails))

</script>


As a side note, 3-letter time-zone IDs, such as PST, should be considered deprecated for most purposes, as many of them are ambiguous. See for example CST, which can refer to 3 completely different time zones.

Upvotes: 5

Sudhakar B
Sudhakar B

Reputation: 1563

Using Intl.DateTimeFormat able to get timezone abbreviation and offset. Below snippet gets timezone with abbreviation and offset.

const timezonesWithoffsets =  Intl.supportedValuesOf('timeZone').map(timeZone => {
  const offset=new Intl.DateTimeFormat('en',{timeZone:timeZone, timeZoneName:'shortOffset'}).formatToParts().find(part => part.type==='timeZoneName').value
  const timeZoneAbbrivation = new Intl.DateTimeFormat('en',{timeZone:timeZone, timeZoneName:'long'}).formatToParts().find(part => part.type==='timeZoneName').value
  return `${timeZone} - ${timeZoneAbbrivation}(${offset})`
}) 

console.log(timezonesWithoffsets)

Upvotes: 7

Related Questions