-
Notifications
You must be signed in to change notification settings - Fork 0
/
formatTimezone.js
58 lines (50 loc) · 1.89 KB
/
formatTimezone.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import abbreviations from './abbreviations.js'
/**
* Formats an IANA timezone string into a specified representation.
*
* Support for timeZoneName = 'longOffset'
* - Chrome 95
* - Edge 95
* - Firefox 91
* - Safari 15.4
* - Node.js 17
*
* @param {string} timezone - The IANA timezone string, e.g., 'America/Los_Angeles'.
* @param {string|string[]} format - One of 'long', 'abbr', 'offset', or an array of these values.
* @param {Date} date - The reference date used to determine the 'long', 'abbr' and 'offset'
* @return {string} The formatted timezone string.
*/
export default function formatTimezone (timezone, format = 'long', date = new Date()) {
if (!timezone) return ''
const formatOpts = { timeZone: timezone }
const formatArray = Array.isArray(format) ? format : [format]
for (let fmt of formatArray) {
switch (fmt) {
case 'city':
const parts = timezone.split('/')
return `${parts[0]} / ${parts.pop()}`.replace(/_/g, ' ')
case 'long':
formatOpts.timeZoneName = 'long'
return new Intl.DateTimeFormat('en-US', formatOpts).format(date).split(', ')[1]
case 'abbr':
formatOpts.timeZoneName = 'long'
const long = new Intl.DateTimeFormat('en-US', formatOpts).format(date).split(', ')[1]
const abbr = abbreviations[long] || abbreviations[long.replace('Standard ', '')]
if (abbr) return abbr
break
case 'offset':
let offset = ''
try {
formatOpts.timeZoneName = 'longOffset'
offset = new Intl.DateTimeFormat('en-US', formatOpts).format(date).split(', ')[1]
} catch {
formatOpts.timeZoneName = 'short'
offset = new Intl.DateTimeFormat('en-US', formatOpts).format(date).split(', ')[1]
}
return offset === 'GMT' ? 'GMT+00:00' : offset
default:
throw new Error('Format option must be one of \'city\', \'long\', \'abbr\' or \'offset\'')
}
}
return ''
}