Created
October 18, 2023 02:45
-
-
Save westc/fed8f6a71a63bcaa2159d3638f262cfe to your computer and use it in GitHub Desktop.
Uses the new Intl API to format a date as a string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var formatIntlDate = (() => { | |
const CODE_TO_PROP_NAME = { | |
Y: ['year', 'numeric'], | |
M: ['month', 'long'], | |
D: ['day', 'numeric'], | |
WD: ['weekday', 'long'], | |
h: ['hour', '2-digit'], | |
m: ['minute', '2-digit'], | |
s: ['second', '2-digit'], | |
ms: ['fractionalSecondDigits', 3], | |
DS: ['dateStyle', 'full'], | |
TS: ['timeStyle', 'full'], | |
}; | |
const CODES = Object.keys(CODE_TO_PROP_NAME).sort( | |
(a, b) => a.length === b.length | |
? a < b ? -1 : 1 | |
: (b.length - a.length) | |
).join('|'); | |
const RGX = new RegExp( | |
`%(${CODES})(?:<(numeric|2-digit|long|narrow|short|medium|1|2|3)>)?|([%<>])\\3`, | |
'g' | |
); | |
/** | |
* Uses the new Intl API to format a date as a string. | |
* @param {Date} date | |
* @param {?FormatIntlDateOptions=} opt_options | |
* @returns {string} | |
*/ | |
function formatIntlDate(date, opt_options) { | |
const {timeZone, format, locale, dateStyle, timeStyle} = opt_options ?? {}; | |
if ('string' === typeof format) { | |
return format.replace(RGX, (m, id, format, escaped) => { | |
if (escaped) return escaped; | |
try { | |
const [name, defaultValue] = CODE_TO_PROP_NAME[id]; | |
return new Intl.DateTimeFormat(locale, { | |
[name]: format || defaultValue, | |
timeZone | |
}).format(date); | |
} catch(e){} | |
return m; | |
}); | |
} | |
return new Intl.DateTimeFormat( | |
locale, | |
{ | |
dateStyle: dateStyle ?? 'full', | |
timeStyle: timeStyle ?? 'full', | |
timeZone | |
} | |
).format(date); | |
} | |
/** | |
* @typedef FormatIntlDateOptions | |
* @property {?string=} timeZone | |
* @property {?string=} format | |
* @property {?string=} locale | |
* @property {?("full"|"long"|"medium"|"short")=} dateStyle | |
* @property {?("full"|"long"|"medium"|"short")=} timeStyle | |
*/ | |
return formatIntlDate; | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log( | |
formatIntlDate(new Date, { | |
format: 'It is currently %WD<short> (AKA "%WD") in Adelaide.', | |
timeZone: 'Australia/Adelaide' | |
}) | |
); | |
console.log( | |
formatIntlDate(new Date, { | |
format: 'It is currently %WD<short> (AKA "%WD") in Hawaii.', | |
timeZone: 'US/Hawaii' | |
}) | |
); | |
for (const locale of ['en', 'en-AU', 'en-GB', 'en-US', 'es', 'es-419', 'es-BR', 'es-ES', 'es-MX', 'es-BO', 'es-AR', 'es-CO', 'pt', 'pt-BR', 'pt-PT', 'pt-AO', 'pt-CH', 'pt-CV', 'pt-GQ', 'pt-GW', 'pt-LU', 'pt-MO', 'pt-MZ', 'pt-ST', 'pt-TL', 'qu', 'qu-BO', 'qu-EC', 'qu-PE', 'sr', 'vi', 'vi-VN', 'sv', 'sw', 'zh', 'de', 'da', 'cs', 'ca', 'bo', 'bg', 'ar', 'af', 'el', 'fil', 'ga', 'fr', 'gl', 'haw', 'he', 'it', 'ko', 'mk', 'nds', 'nl', 'ru', 'sn', 'uk']) { | |
console.log(`${locale}:\n\t${formatIntlDate(new Date, {locale})}`); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment