@bbn/bbn 2.0.38 → 2.0.40
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.
- package/dist/bbn.js +1 -1
- package/dist/bbn.js.map +1 -1
- package/dist/dt/functions/buildLocaleFromIntl.js +41 -48
- package/package.json +1 -1
|
@@ -4,78 +4,70 @@ import numProperties from "../../fn/object/numProperties.js";
|
|
|
4
4
|
* Build a token pattern (YYYY, MM, DD, dddd, HH, II, SS, A, z) from Intl parts.
|
|
5
5
|
* Uses Intl options to distinguish MMM vs MMMM, ddd vs dddd, etc.
|
|
6
6
|
*/
|
|
7
|
-
function partsToPattern(parts,
|
|
7
|
+
function partsToPattern(parts, resolved, requestedOpts) {
|
|
8
8
|
let pattern = '';
|
|
9
|
+
const hourCycle = resolved.hourCycle;
|
|
9
10
|
const hasDayPeriod = parts.some(p => p.type === 'dayPeriod');
|
|
10
11
|
const is12h = hasDayPeriod || hourCycle === 'h12' || hourCycle === 'h11';
|
|
11
|
-
//
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const hasYear = !!opts.year;
|
|
16
|
-
const hasMonth = !!opts.month;
|
|
17
|
-
const hasDay = !!opts.day;
|
|
18
|
-
const hasWeekday = !!opts.weekday;
|
|
19
|
-
const hasTextMonth = opts.month === 'short' || opts.month === 'long';
|
|
20
|
-
const isAllNumericDate = hasYear && hasMonth && hasDay &&
|
|
21
|
-
yearIsNumeric && monthIsNumeric && dayIsNumeric &&
|
|
22
|
-
!hasWeekday && !hasTextMonth;
|
|
12
|
+
// ALL NUMERIC (not 2-digit): year, month and day resolved as "numeric"
|
|
13
|
+
const allNumericNonPadded = resolved.year === 'numeric' &&
|
|
14
|
+
resolved.month === 'numeric' &&
|
|
15
|
+
resolved.day === 'numeric';
|
|
23
16
|
for (const p of parts) {
|
|
24
17
|
switch (p.type) {
|
|
25
|
-
case 'year':
|
|
26
|
-
if
|
|
18
|
+
case 'year': {
|
|
19
|
+
// Use YY only if locale actually resolved 2-digit
|
|
20
|
+
if (resolved.year === '2-digit') {
|
|
27
21
|
pattern += 'YY';
|
|
28
22
|
}
|
|
29
23
|
else {
|
|
30
24
|
pattern += 'YYYY';
|
|
31
25
|
}
|
|
32
26
|
break;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
pattern += 'MMM';
|
|
27
|
+
}
|
|
28
|
+
case 'month': {
|
|
29
|
+
// textual month
|
|
30
|
+
if (requestedOpts.month === 'short' || requestedOpts.month === 'long') {
|
|
31
|
+
pattern += requestedOpts.month === 'long' ? 'MMMM' : 'MMM';
|
|
32
|
+
break;
|
|
40
33
|
}
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
// ALL NUMERIC and non-padded → always use M
|
|
35
|
+
if (allNumericNonPadded) {
|
|
36
|
+
pattern += 'M';
|
|
37
|
+
break;
|
|
43
38
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
pattern +=
|
|
39
|
+
// numeric / 2-digit generic case
|
|
40
|
+
if (/^\d+$/.test(p.value)) {
|
|
41
|
+
pattern += p.value.length === 2 ? 'MM' : 'M';
|
|
47
42
|
}
|
|
48
43
|
else {
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
pattern += p.value.length === 2 ? 'MM' : 'M';
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
pattern += p.value.length > 3 ? 'MMMM' : 'MMM';
|
|
55
|
-
}
|
|
44
|
+
// fallback (shouldn't really happen without text month)
|
|
45
|
+
pattern += p.value.length > 3 ? 'MMMM' : 'MMM';
|
|
56
46
|
}
|
|
57
47
|
break;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
}
|
|
49
|
+
case 'day': {
|
|
50
|
+
// ALL NUMERIC and non-padded → always use D
|
|
51
|
+
if (allNumericNonPadded) {
|
|
61
52
|
pattern += 'D';
|
|
53
|
+
break;
|
|
62
54
|
}
|
|
63
|
-
|
|
64
|
-
pattern += p.value.length === 2 ? 'DD' : 'D';
|
|
65
|
-
}
|
|
55
|
+
pattern += p.value.length === 2 ? 'DD' : 'D';
|
|
66
56
|
break;
|
|
67
|
-
|
|
68
|
-
|
|
57
|
+
}
|
|
58
|
+
case 'weekday': {
|
|
59
|
+
if (requestedOpts.weekday === 'short' || requestedOpts.weekday === 'narrow') {
|
|
69
60
|
pattern += 'ddd';
|
|
70
61
|
}
|
|
71
|
-
else if (
|
|
62
|
+
else if (requestedOpts.weekday === 'long') {
|
|
72
63
|
pattern += 'dddd';
|
|
73
64
|
}
|
|
74
65
|
else {
|
|
75
66
|
pattern += p.value.length > 3 ? 'dddd' : 'ddd';
|
|
76
67
|
}
|
|
77
68
|
break;
|
|
78
|
-
|
|
69
|
+
}
|
|
70
|
+
case 'hour': {
|
|
79
71
|
if (is12h) {
|
|
80
72
|
pattern += p.value.length === 2 ? 'hh' : 'h';
|
|
81
73
|
}
|
|
@@ -83,6 +75,7 @@ function partsToPattern(parts, hourCycle, opts) {
|
|
|
83
75
|
pattern += p.value.length === 2 ? 'HH' : 'H';
|
|
84
76
|
}
|
|
85
77
|
break;
|
|
78
|
+
}
|
|
86
79
|
case 'minute':
|
|
87
80
|
pattern += 'II';
|
|
88
81
|
break;
|
|
@@ -96,7 +89,7 @@ function partsToPattern(parts, hourCycle, opts) {
|
|
|
96
89
|
pattern += 'z';
|
|
97
90
|
break;
|
|
98
91
|
case 'literal': {
|
|
99
|
-
// Wrap literals in [ ... ] so your parser
|
|
92
|
+
// Wrap literals in [ ... ] so your parser won't confuse them with tokens
|
|
100
93
|
if (p.value.length) {
|
|
101
94
|
const v = p.value.replace(/]/g, '\\]');
|
|
102
95
|
pattern += `[${v}]`;
|
|
@@ -154,7 +147,7 @@ export function getCommonFormatsForLocale(lng) {
|
|
|
154
147
|
const fmt = new Intl.DateTimeFormat(lng, opts);
|
|
155
148
|
const parts = fmt.formatToParts(sample);
|
|
156
149
|
const resolved = fmt.resolvedOptions();
|
|
157
|
-
const pattern = partsToPattern(parts, resolved
|
|
150
|
+
const pattern = partsToPattern(parts, resolved, opts);
|
|
158
151
|
if (!seenDatePatterns.has(pattern)) {
|
|
159
152
|
seenDatePatterns.add(pattern);
|
|
160
153
|
date.push({
|
|
@@ -181,7 +174,7 @@ export function getCommonFormatsForLocale(lng) {
|
|
|
181
174
|
const fmt = new Intl.DateTimeFormat(lng, opts);
|
|
182
175
|
const parts = fmt.formatToParts(sample);
|
|
183
176
|
const resolved = fmt.resolvedOptions();
|
|
184
|
-
const pattern = partsToPattern(parts, resolved
|
|
177
|
+
const pattern = partsToPattern(parts, resolved, opts);
|
|
185
178
|
if (!seenTimePatterns.has(pattern)) {
|
|
186
179
|
seenTimePatterns.add(pattern);
|
|
187
180
|
time.push({
|
|
@@ -198,7 +191,7 @@ export function getCommonFormatsForLocale(lng) {
|
|
|
198
191
|
const fmt = new Intl.DateTimeFormat(lng, opts);
|
|
199
192
|
const parts = fmt.formatToParts(sample);
|
|
200
193
|
const resolved = fmt.resolvedOptions();
|
|
201
|
-
const pattern = partsToPattern(parts, resolved
|
|
194
|
+
const pattern = partsToPattern(parts, resolved, opts);
|
|
202
195
|
if (!seenDateTimePatterns.has(pattern)) {
|
|
203
196
|
seenDateTimePatterns.add(pattern);
|
|
204
197
|
datetime.push({
|