this repo has no description
1import localeMatch from './locale-match.js';
2import mem from './mem.js';
3
4function initLocales() {
5 const newLocales = [...navigator.languages];
6 try {
7 const dtfLocale = new Intl.DateTimeFormat().resolvedOptions().locale;
8 if (!newLocales.includes(dtfLocale)) {
9 newLocales.unshift(dtfLocale);
10 }
11 } catch {}
12 return newLocales;
13}
14
15let locales = initLocales();
16
17// For testing: refresh locales from current navigator state
18export function refreshLocales() {
19 locales = initLocales();
20}
21
22const createLocale = mem((language, options = {}) => {
23 try {
24 return new Intl.Locale(language, options);
25 } catch {
26 // Fallback to simple string splitting
27 // May not work properly due to how complicated this is
28 if (!language) return null;
29
30 // https://www.w3.org/International/articles/language-tags/
31 // Parts: language-extlang-script-region-variant-extension-privateuse
32 const [langPart, ...parts] = language.split('-', 4);
33 const regionPart = parts.pop() || null;
34 const fallbackLocale = {
35 language: langPart,
36 region: regionPart,
37 ...options,
38 toString: () => {
39 const lang = fallbackLocale.language;
40 const middle = parts.length > 0 ? `-${parts.join('-')}-` : '-';
41 const reg = fallbackLocale.region;
42 return reg ? `${lang}${middle}${reg}` : lang;
43 },
44 };
45 return fallbackLocale;
46 }
47});
48
49const _DateTimeFormat = (locale, opts) => {
50 const options = opts;
51
52 const appLocale = createLocale(locale);
53
54 // Find first user locale with a region
55 let userRegion = null;
56 for (const loc of locales) {
57 const region = createLocale(loc)?.region;
58 if (region) {
59 userRegion = region;
60 break;
61 }
62 }
63
64 const userRegionLocale =
65 userRegion && appLocale && appLocale.region !== userRegion
66 ? createLocale(appLocale.language, {
67 ...appLocale,
68 region: userRegion,
69 })?.toString()
70 : null;
71
72 const matchedLocale = localeMatch(
73 [userRegionLocale, locale, locale?.replace(/-[a-z]+$/i, '')],
74 locales,
75 locale,
76 );
77
78 try {
79 return new Intl.DateTimeFormat(matchedLocale, options);
80 } catch {
81 return new Intl.DateTimeFormat(undefined, options);
82 }
83};
84
85const DateTimeFormat = mem(_DateTimeFormat);
86
87export default DateTimeFormat;