@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
- else
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
- pattern += is12h ? (p.value.length === 2 ? 'hh' : 'h') : (p.value.length === 2 ? 'HH' : 'H');
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
- * Returns all common date/time/datetime formats + weekday formats for a given locale.
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
- const dateStyles = ['full', 'long', 'medium', 'short'];
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 result = {
57
- date: [],
58
- time: [],
59
- datetime: [],
60
- dateWithWeekday: [],
61
- datetimeWithWeekday: []
62
- };
63
- // --- Date only ---
64
- for (const ds of dateStyles) {
65
- const options = { dateStyle: ds };
66
- const fmt = new Intl.DateTimeFormat(lng, options);
67
- const parts = fmt.formatToParts(sample);
68
- result.date.push({
69
- style: ds,
70
- pattern: partsToPattern(parts, fmt.resolvedOptions().hourCycle),
71
- sample: fmt.format(sample),
72
- options
73
- });
74
- }
75
- // --- Time only ---
76
- for (const ts of timeStyles) {
77
- const options = { timeStyle: ts };
78
- const fmt = new Intl.DateTimeFormat(lng, options);
79
- const parts = fmt.formatToParts(sample);
80
- result.time.push({
81
- style: ts,
82
- pattern: partsToPattern(parts, fmt.resolvedOptions().hourCycle),
83
- sample: fmt.format(sample),
84
- options
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
- // --- Date + Time ---
88
- for (const ds of dateStyles) {
89
- for (const ts of timeStyles) {
90
- const options = { dateStyle: ds, timeStyle: ts };
91
- const fmt = new Intl.DateTimeFormat(lng, options);
92
- const parts = fmt.formatToParts(sample);
93
- result.datetime.push({
94
- dateStyle: ds,
95
- timeStyle: ts,
96
- pattern: partsToPattern(parts, fmt.resolvedOptions().hourCycle),
97
- sample: fmt.format(sample),
98
- options
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
- // --- Date with Weekday (long + short) ---
103
- for (const ds of dateStyles) {
104
- for (const w of ["long", "short"]) {
105
- const options = { dateStyle: ds, weekday: w };
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
- result.dateWithWeekday.push({
109
- style: ds,
110
- weekday: w,
111
- pattern: partsToPattern(parts, fmt.resolvedOptions().hourCycle),
112
- sample: fmt.format(sample),
113
- options
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 result;
193
+ return { date, time, datetime };
136
194
  }
137
195
  export default function buildLocaleFromIntl() {
138
196
  if (numProperties(bbn.dt.locales)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbn/bbn",
3
- "version": "2.0.31",
3
+ "version": "2.0.33",
4
4
  "description": "Javascript toolkit",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",