@bbn/bbn 2.0.31 → 2.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1,28 @@
|
|
|
1
|
+
type CommonFormats = {
|
|
2
|
+
date: Array<{
|
|
3
|
+
pattern: string;
|
|
4
|
+
sample: string;
|
|
5
|
+
options: Intl.DateTimeFormatOptions;
|
|
6
|
+
}>;
|
|
7
|
+
time: Array<{
|
|
8
|
+
pattern: string;
|
|
9
|
+
sample: string;
|
|
10
|
+
options: Intl.DateTimeFormatOptions;
|
|
11
|
+
}>;
|
|
12
|
+
datetime: Array<{
|
|
13
|
+
pattern: string;
|
|
14
|
+
sample: string;
|
|
15
|
+
options: Intl.DateTimeFormatOptions;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Enumerate common date, time and datetime formats for a locale, by iterating
|
|
20
|
+
* over combinations of:
|
|
21
|
+
* - weekday / year / month / day
|
|
22
|
+
* - hour / minute / second / timeZoneName
|
|
23
|
+
*
|
|
24
|
+
* No dateStyle/timeStyle is used, so we can safely combine date + time.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getCommonFormatsForLocale(lng: string | string[]): CommonFormats;
|
|
1
27
|
export default function buildLocaleFromIntl(): void;
|
|
28
|
+
export {};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import extend from "../../fn/object/extend.js";
|
|
2
2
|
import numProperties from "../../fn/object/numProperties.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a token pattern (YYYY, MM, DD, dddd, HH, II, SS, A, z) from Intl parts.
|
|
5
|
+
*/
|
|
3
6
|
function partsToPattern(parts, hourCycle) {
|
|
4
7
|
let pattern = '';
|
|
5
8
|
const hasDayPeriod = parts.some(p => p.type === 'dayPeriod');
|
|
@@ -10,10 +13,12 @@ function partsToPattern(parts, hourCycle) {
|
|
|
10
13
|
pattern += 'YYYY';
|
|
11
14
|
break;
|
|
12
15
|
case 'month':
|
|
13
|
-
if (/^\d+$/.test(p.value))
|
|
16
|
+
if (/^\d+$/.test(p.value)) {
|
|
14
17
|
pattern += p.value.length === 2 ? 'MM' : 'M';
|
|
15
|
-
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
16
20
|
pattern += p.value.length > 3 ? 'MMMM' : 'MMM';
|
|
21
|
+
}
|
|
17
22
|
break;
|
|
18
23
|
case 'day':
|
|
19
24
|
pattern += p.value.length === 2 ? 'DD' : 'D';
|
|
@@ -22,7 +27,12 @@ function partsToPattern(parts, hourCycle) {
|
|
|
22
27
|
pattern += p.value.length > 3 ? 'dddd' : 'ddd';
|
|
23
28
|
break;
|
|
24
29
|
case 'hour':
|
|
25
|
-
|
|
30
|
+
if (is12h) {
|
|
31
|
+
pattern += p.value.length === 2 ? 'hh' : 'h';
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
pattern += p.value.length === 2 ? 'HH' : 'H';
|
|
35
|
+
}
|
|
26
36
|
break;
|
|
27
37
|
case 'minute':
|
|
28
38
|
pattern += 'II';
|
|
@@ -37,8 +47,6 @@ function partsToPattern(parts, hourCycle) {
|
|
|
37
47
|
pattern += 'z';
|
|
38
48
|
break;
|
|
39
49
|
case 'literal':
|
|
40
|
-
pattern += p.value;
|
|
41
|
-
break;
|
|
42
50
|
default:
|
|
43
51
|
pattern += p.value;
|
|
44
52
|
break;
|
|
@@ -47,92 +55,142 @@ function partsToPattern(parts, hourCycle) {
|
|
|
47
55
|
return pattern;
|
|
48
56
|
}
|
|
49
57
|
/**
|
|
50
|
-
*
|
|
58
|
+
* Enumerate common date, time and datetime formats for a locale, by iterating
|
|
59
|
+
* over combinations of:
|
|
60
|
+
* - weekday / year / month / day
|
|
61
|
+
* - hour / minute / second / timeZoneName
|
|
62
|
+
*
|
|
63
|
+
* No dateStyle/timeStyle is used, so we can safely combine date + time.
|
|
51
64
|
*/
|
|
52
|
-
function getCommonFormatsForLocale(lng) {
|
|
53
|
-
|
|
54
|
-
const timeStyles = ['full', 'long', 'medium', 'short'];
|
|
65
|
+
export function getCommonFormatsForLocale(lng) {
|
|
66
|
+
// Fixed sample: 2 Jan 2000, 13:45:30 UTC
|
|
55
67
|
const sample = new Date(Date.UTC(2000, 0, 2, 13, 45, 30));
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
68
|
+
const date = [];
|
|
69
|
+
const time = [];
|
|
70
|
+
const datetime = [];
|
|
71
|
+
const seenDatePatterns = new Set();
|
|
72
|
+
const seenTimePatterns = new Set();
|
|
73
|
+
const seenDateTimePatterns = new Set();
|
|
74
|
+
// ---- 1) DATE formats: combinations of weekday/year/month/day ----
|
|
75
|
+
const weekdayOptions = [
|
|
76
|
+
undefined,
|
|
77
|
+
'short',
|
|
78
|
+
'long'
|
|
79
|
+
];
|
|
80
|
+
const yearOptions = [
|
|
81
|
+
undefined,
|
|
82
|
+
'numeric',
|
|
83
|
+
'2-digit'
|
|
84
|
+
];
|
|
85
|
+
const monthOptions = [undefined, 'numeric', '2-digit', 'short', 'long'];
|
|
86
|
+
const dayOptions = [
|
|
87
|
+
undefined,
|
|
88
|
+
'numeric',
|
|
89
|
+
'2-digit'
|
|
90
|
+
];
|
|
91
|
+
const dateOptionsList = [];
|
|
92
|
+
for (const weekday of weekdayOptions) {
|
|
93
|
+
for (const year of yearOptions) {
|
|
94
|
+
for (const month of monthOptions) {
|
|
95
|
+
for (const day of dayOptions) {
|
|
96
|
+
// Skip combos with no actual date fields
|
|
97
|
+
if (!year && !month && !day) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const options = {};
|
|
101
|
+
if (weekday)
|
|
102
|
+
options.weekday = weekday;
|
|
103
|
+
if (year)
|
|
104
|
+
options.year = year;
|
|
105
|
+
if (month)
|
|
106
|
+
options.month = month;
|
|
107
|
+
if (day)
|
|
108
|
+
options.day = day;
|
|
109
|
+
const fmt = new Intl.DateTimeFormat(lng, options);
|
|
110
|
+
const parts = fmt.formatToParts(sample);
|
|
111
|
+
const resolved = fmt.resolvedOptions();
|
|
112
|
+
const pattern = partsToPattern(parts, resolved.hourCycle);
|
|
113
|
+
if (!seenDatePatterns.has(pattern)) {
|
|
114
|
+
seenDatePatterns.add(pattern);
|
|
115
|
+
dateOptionsList.push(options);
|
|
116
|
+
date.push({
|
|
117
|
+
pattern,
|
|
118
|
+
sample: fmt.format(sample),
|
|
119
|
+
options
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
86
125
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
126
|
+
const hourOptions = ['numeric', '2-digit'];
|
|
127
|
+
const minuteOptions = [
|
|
128
|
+
undefined,
|
|
129
|
+
'numeric',
|
|
130
|
+
'2-digit'
|
|
131
|
+
];
|
|
132
|
+
const secondOptions = [
|
|
133
|
+
undefined,
|
|
134
|
+
'numeric',
|
|
135
|
+
'2-digit'
|
|
136
|
+
];
|
|
137
|
+
const tzNameOptions = [
|
|
138
|
+
undefined,
|
|
139
|
+
'short',
|
|
140
|
+
'long'
|
|
141
|
+
];
|
|
142
|
+
const timeOptionsList = [];
|
|
143
|
+
for (const hour of hourOptions) {
|
|
144
|
+
for (const minute of minuteOptions) {
|
|
145
|
+
for (const second of secondOptions) {
|
|
146
|
+
for (const tzName of tzNameOptions) {
|
|
147
|
+
// Need at least hour to be a "time"
|
|
148
|
+
if (!hour) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const options = { hour };
|
|
152
|
+
if (minute)
|
|
153
|
+
options.minute = minute;
|
|
154
|
+
if (second)
|
|
155
|
+
options.second = second;
|
|
156
|
+
if (tzName)
|
|
157
|
+
options.timeZoneName = tzName;
|
|
158
|
+
const fmt = new Intl.DateTimeFormat(lng, options);
|
|
159
|
+
const parts = fmt.formatToParts(sample);
|
|
160
|
+
const resolved = fmt.resolvedOptions();
|
|
161
|
+
const pattern = partsToPattern(parts, resolved.hourCycle);
|
|
162
|
+
if (!seenTimePatterns.has(pattern)) {
|
|
163
|
+
seenTimePatterns.add(pattern);
|
|
164
|
+
timeOptionsList.push(options);
|
|
165
|
+
time.push({
|
|
166
|
+
pattern,
|
|
167
|
+
sample: fmt.format(sample),
|
|
168
|
+
options
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
100
173
|
}
|
|
101
174
|
}
|
|
102
|
-
//
|
|
103
|
-
for (const
|
|
104
|
-
for (const
|
|
105
|
-
const options = {
|
|
175
|
+
// ---- 3) DATETIME formats: each dateOption × each timeOption ----
|
|
176
|
+
for (const dateOpts of dateOptionsList) {
|
|
177
|
+
for (const timeOpts of timeOptionsList) {
|
|
178
|
+
const options = Object.assign(Object.assign({}, dateOpts), timeOpts);
|
|
106
179
|
const fmt = new Intl.DateTimeFormat(lng, options);
|
|
107
180
|
const parts = fmt.formatToParts(sample);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
// --- Date + Time + Weekday ---
|
|
118
|
-
for (const ds of dateStyles) {
|
|
119
|
-
for (const ts of timeStyles) {
|
|
120
|
-
for (const w of ["long", "short"]) {
|
|
121
|
-
const options = { dateStyle: ds, timeStyle: ts, weekday: w };
|
|
122
|
-
const fmt = new Intl.DateTimeFormat(lng, options);
|
|
123
|
-
const parts = fmt.formatToParts(sample);
|
|
124
|
-
result.datetimeWithWeekday.push({
|
|
125
|
-
dateStyle: ds,
|
|
126
|
-
timeStyle: ts,
|
|
127
|
-
weekday: w,
|
|
128
|
-
pattern: partsToPattern(parts, fmt.resolvedOptions().hourCycle),
|
|
181
|
+
const resolved = fmt.resolvedOptions();
|
|
182
|
+
const pattern = partsToPattern(parts, resolved.hourCycle);
|
|
183
|
+
if (!seenDateTimePatterns.has(pattern)) {
|
|
184
|
+
seenDateTimePatterns.add(pattern);
|
|
185
|
+
datetime.push({
|
|
186
|
+
pattern,
|
|
129
187
|
sample: fmt.format(sample),
|
|
130
188
|
options
|
|
131
189
|
});
|
|
132
190
|
}
|
|
133
191
|
}
|
|
134
192
|
}
|
|
135
|
-
return
|
|
193
|
+
return { date, time, datetime };
|
|
136
194
|
}
|
|
137
195
|
export default function buildLocaleFromIntl() {
|
|
138
196
|
if (numProperties(bbn.dt.locales)) {
|