@thi.ng/date 2.5.5 → 2.5.6

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/format.js CHANGED
@@ -1,402 +1,257 @@
1
1
  import { isFunction } from "@thi.ng/checks/is-function";
2
2
  import { isString } from "@thi.ng/checks/is-string";
3
3
  import { Z2, Z3, Z4 } from "@thi.ng/strings/pad-left";
4
- import { DAY, HOUR, MINUTE, MONTH, SECOND, YEAR, } from "./api.js";
4
+ import {
5
+ DAY,
6
+ HOUR,
7
+ MINUTE,
8
+ MONTH,
9
+ SECOND,
10
+ YEAR
11
+ } from "./api.js";
5
12
  import { ensureDate, ensureEpoch } from "./checks.js";
6
13
  import { decomposeDuration } from "./duration.js";
7
14
  import { LOCALE, tense, units, unitsLessThan } from "./i18n.js";
8
15
  import { __idToPrecision, __precisionToID } from "./internal/precision.js";
9
16
  import { decomposeDifference, difference } from "./relative.js";
10
17
  import { weekInYear } from "./units.js";
11
- export const FORMATTERS = {
12
- /**
13
- * Full year (4 digits)
14
- */
15
- yyyy: (d) => Z4(d.getFullYear()),
16
- /**
17
- * Short year (2 digits, e.g. `2020 % 100` => 20)
18
- */
19
- yy: (d) => Z2(d.getFullYear() % 100),
20
- /**
21
- * Month name, using current {@link LOCALE} (e.g. `Feb`)
22
- */
23
- MMM: (d) => LOCALE.months[d.getMonth()],
24
- /**
25
- * Zero-padded 2-digit month
26
- */
27
- MM: (d) => Z2(d.getMonth() + 1),
28
- /**
29
- * Unpadded month
30
- */
31
- M: (d) => String(d.getMonth() + 1),
32
- /**
33
- * Zero-padded 2-digit day of month
34
- */
35
- dd: (d) => Z2(d.getDate()),
36
- /**
37
- * Unpadded day of month
38
- */
39
- d: (d) => String(d.getDate()),
40
- /**
41
- * Weekday name, using current {@link LOCALE} (e.g. `Mon`)
42
- */
43
- E: (d) => LOCALE.days[d.getDay()],
44
- /**
45
- * Zero-padded 2-digit ISO week number.
46
- */
47
- ww: (d) => Z2(FORMATTERS.w(d, false)),
48
- /**
49
- * Unpadded ISO week number.
50
- */
51
- w: (d) => String(weekInYear(d.getFullYear(), d.getMonth(), d.getDate())),
52
- /**
53
- * Unpadded quarter:
54
- *
55
- * - 1 = Jan - Mar
56
- * - 2 = Apr - Jun
57
- * - 3 = Jul - Sep
58
- * - 4 = Oct - Dec
59
- */
60
- q: (d) => String(((d.getMonth() / 3) | 0) + 1),
61
- /**
62
- * Zero-padded 2-digit hour of day (0-23)
63
- */
64
- HH: (d) => Z2(d.getHours()),
65
- /**
66
- * Unpadded our of day (0-23)
67
- */
68
- H: (d) => String(d.getHours()),
69
- /**
70
- * Zero-padded hour of day (1-12)
71
- */
72
- hh: (d) => {
73
- const h = d.getHours() % 12;
74
- return Z2(h > 0 ? h : 12);
75
- },
76
- /**
77
- * Unpadded hour of day (1-12)
78
- */
79
- h: (d) => {
80
- const h = d.getHours() % 12;
81
- return String(h > 0 ? h : 12);
82
- },
83
- /**
84
- * Zero-padded 2-digit minute of hour
85
- */
86
- mm: (d) => Z2(d.getMinutes()),
87
- /**
88
- * Unpadded minute of hour
89
- */
90
- m: (d) => String(d.getMinutes()),
91
- /**
92
- * Zero-padded 2-digit second of minute
93
- */
94
- ss: (d) => Z2(d.getSeconds()),
95
- /**
96
- * Unpadded second of minute
97
- */
98
- s: (d) => String(d.getSeconds()),
99
- /**
100
- * Zero-padded 3-digit millisecond of second
101
- */
102
- SS: (d) => Z3(d.getMilliseconds()),
103
- /**
104
- * Unpadded millisecond of second
105
- */
106
- S: (d) => String(d.getMilliseconds()),
107
- /**
108
- * 12-hour AM/PM marker (uppercase)
109
- */
110
- A: (d) => String(d.getHours() < 12 ? "AM" : "PM"),
111
- /**
112
- * 12-hour am/pm marker (lowercase)
113
- */
114
- a: (d) => String(d.getHours() < 12 ? "am" : "pm"),
115
- /**
116
- * Timezone offset in signed `HH:mm` format
117
- */
118
- Z: (d, utc = false) => {
119
- const z = utc ? 0 : d.getTimezoneOffset();
120
- const za = Math.abs(z);
121
- return `${z < 0 ? "+" : "-"}${Z2((za / 60) | 0)}:${Z2(za % 60)}`;
122
- },
123
- /**
124
- * Returns literal `"Z"` iff timezone offset is zero (UTC), else the same as
125
- * `Z` formatter.
126
- *
127
- * @param d -
128
- */
129
- ZZ: (d, utc = false) => (utc ? "Z" : FORMATTERS.Z(d, utc)),
130
- /**
131
- * Current {@link LOCALE}'s day-month separator.
132
- */
133
- "/DM": () => LOCALE.sepDM,
134
- /**
135
- * Current {@link LOCALE}'s weekday-day separator.
136
- */
137
- "/ED": () => LOCALE.sepED,
138
- /**
139
- * Current {@link LOCALE}'s hour-minute separator.
140
- */
141
- "/HM": () => LOCALE.sepHM,
142
- /**
143
- * Current {@link LOCALE}'s month-year separator.
144
- */
145
- "/MY": () => LOCALE.sepMY,
18
+ const FORMATTERS = {
19
+ /**
20
+ * Full year (4 digits)
21
+ */
22
+ yyyy: (d) => Z4(d.getFullYear()),
23
+ /**
24
+ * Short year (2 digits, e.g. `2020 % 100` => 20)
25
+ */
26
+ yy: (d) => Z2(d.getFullYear() % 100),
27
+ /**
28
+ * Month name, using current {@link LOCALE} (e.g. `Feb`)
29
+ */
30
+ MMM: (d) => LOCALE.months[d.getMonth()],
31
+ /**
32
+ * Zero-padded 2-digit month
33
+ */
34
+ MM: (d) => Z2(d.getMonth() + 1),
35
+ /**
36
+ * Unpadded month
37
+ */
38
+ M: (d) => String(d.getMonth() + 1),
39
+ /**
40
+ * Zero-padded 2-digit day of month
41
+ */
42
+ dd: (d) => Z2(d.getDate()),
43
+ /**
44
+ * Unpadded day of month
45
+ */
46
+ d: (d) => String(d.getDate()),
47
+ /**
48
+ * Weekday name, using current {@link LOCALE} (e.g. `Mon`)
49
+ */
50
+ E: (d) => LOCALE.days[d.getDay()],
51
+ /**
52
+ * Zero-padded 2-digit ISO week number.
53
+ */
54
+ ww: (d) => Z2(FORMATTERS.w(d, false)),
55
+ /**
56
+ * Unpadded ISO week number.
57
+ */
58
+ w: (d) => String(weekInYear(d.getFullYear(), d.getMonth(), d.getDate())),
59
+ /**
60
+ * Unpadded quarter:
61
+ *
62
+ * - 1 = Jan - Mar
63
+ * - 2 = Apr - Jun
64
+ * - 3 = Jul - Sep
65
+ * - 4 = Oct - Dec
66
+ */
67
+ q: (d) => String((d.getMonth() / 3 | 0) + 1),
68
+ /**
69
+ * Zero-padded 2-digit hour of day (0-23)
70
+ */
71
+ HH: (d) => Z2(d.getHours()),
72
+ /**
73
+ * Unpadded our of day (0-23)
74
+ */
75
+ H: (d) => String(d.getHours()),
76
+ /**
77
+ * Zero-padded hour of day (1-12)
78
+ */
79
+ hh: (d) => {
80
+ const h = d.getHours() % 12;
81
+ return Z2(h > 0 ? h : 12);
82
+ },
83
+ /**
84
+ * Unpadded hour of day (1-12)
85
+ */
86
+ h: (d) => {
87
+ const h = d.getHours() % 12;
88
+ return String(h > 0 ? h : 12);
89
+ },
90
+ /**
91
+ * Zero-padded 2-digit minute of hour
92
+ */
93
+ mm: (d) => Z2(d.getMinutes()),
94
+ /**
95
+ * Unpadded minute of hour
96
+ */
97
+ m: (d) => String(d.getMinutes()),
98
+ /**
99
+ * Zero-padded 2-digit second of minute
100
+ */
101
+ ss: (d) => Z2(d.getSeconds()),
102
+ /**
103
+ * Unpadded second of minute
104
+ */
105
+ s: (d) => String(d.getSeconds()),
106
+ /**
107
+ * Zero-padded 3-digit millisecond of second
108
+ */
109
+ SS: (d) => Z3(d.getMilliseconds()),
110
+ /**
111
+ * Unpadded millisecond of second
112
+ */
113
+ S: (d) => String(d.getMilliseconds()),
114
+ /**
115
+ * 12-hour AM/PM marker (uppercase)
116
+ */
117
+ A: (d) => String(d.getHours() < 12 ? "AM" : "PM"),
118
+ /**
119
+ * 12-hour am/pm marker (lowercase)
120
+ */
121
+ a: (d) => String(d.getHours() < 12 ? "am" : "pm"),
122
+ /**
123
+ * Timezone offset in signed `HH:mm` format
124
+ */
125
+ Z: (d, utc = false) => {
126
+ const z = utc ? 0 : d.getTimezoneOffset();
127
+ const za = Math.abs(z);
128
+ return `${z < 0 ? "+" : "-"}${Z2(za / 60 | 0)}:${Z2(za % 60)}`;
129
+ },
130
+ /**
131
+ * Returns literal `"Z"` iff timezone offset is zero (UTC), else the same as
132
+ * `Z` formatter.
133
+ *
134
+ * @param d -
135
+ */
136
+ ZZ: (d, utc = false) => utc ? "Z" : FORMATTERS.Z(d, utc),
137
+ /**
138
+ * Current {@link LOCALE}'s day-month separator.
139
+ */
140
+ "/DM": () => LOCALE.sepDM,
141
+ /**
142
+ * Current {@link LOCALE}'s weekday-day separator.
143
+ */
144
+ "/ED": () => LOCALE.sepED,
145
+ /**
146
+ * Current {@link LOCALE}'s hour-minute separator.
147
+ */
148
+ "/HM": () => LOCALE.sepHM,
149
+ /**
150
+ * Current {@link LOCALE}'s month-year separator.
151
+ */
152
+ "/MY": () => LOCALE.sepMY
146
153
  };
147
- /**
148
- * Returns a new date formatter for given array of format strings (or
149
- * functions). The returned function accepts timestamps (epoch), `Date` or
150
- * `DateTime` instances and accepts an optional boolean arg to output UTC
151
- * instead of local time (default).
152
- *
153
- * @remarks
154
- * If no date is given to the returned formatter, `Date.now()` will be used by
155
- * default.
156
- *
157
- * See {@link FORMATTERS} for available date component format IDs. To escape a
158
- * formatter and use as a string literal, prefix the term with `\\`.
159
- *
160
- * @example
161
- * ```ts
162
- * const fmt = defFormat(["yyyy", "-", "MM", "-", "dd"]);
163
- *
164
- * fmt(new Date(2015, 3, 23))
165
- * // "2015-04-23"
166
- *
167
- * defFormat(["\\yyyy"])(new Date(2015, 3, 23))
168
- * // "yyyy"
169
- * ```
170
- *
171
- * @param fmt -
172
- */
173
- export const defFormat = (fmt) => (x = Date.now(), utc = false) => {
174
- let d = ensureDate(x);
175
- utc && (d = new Date(d.getTime() + d.getTimezoneOffset() * MINUTE));
176
- return fmt
177
- .map((x) => {
178
- let fn;
179
- return isString(x)
180
- ? x.startsWith("\\")
181
- ? x.substring(1)
182
- : (fn = FORMATTERS[x])
183
- ? fn(d, utc)
184
- : x
185
- : isFunction(x)
186
- ? x(d, utc)
187
- : x;
188
- })
189
- .join("");
154
+ const defFormat = (fmt) => (x = Date.now(), utc = false) => {
155
+ let d = ensureDate(x);
156
+ utc && (d = new Date(d.getTime() + d.getTimezoneOffset() * MINUTE));
157
+ return fmt.map((x2) => {
158
+ let fn;
159
+ return isString(x2) ? x2.startsWith("\\") ? x2.substring(1) : (fn = FORMATTERS[x2]) ? fn(d, utc) : x2 : isFunction(x2) ? x2(d, utc) : x2;
160
+ }).join("");
190
161
  };
191
- /**
192
- * Format preset, e.g. `2020-09-19`
193
- */
194
- export const FMT_yyyyMMdd = defFormat(["yyyy", "-", "MM", "-", "dd"]);
195
- /**
196
- * Format preset, e.g. `9/19/2020`
197
- */
198
- export const FMT_Mdyyyy = defFormat(["M", "/", "d", "/", "yyyy"]);
199
- /**
200
- * Format preset, e.g. `Sep 19 2020`. Uses current `LOCALE`, see
201
- * {@link setLocale}.
202
- */
203
- export const FMT_MMMdyyyy = defFormat(["MMM", " ", "d", " ", "yyyy"]);
204
- /**
205
- * Format preset, e.g. `19.9.2020`
206
- */
207
- export const FMT_dMyyyy = defFormat(["d", "~", "M", "~", "yyyy"]);
208
- /**
209
- * Format preset, e.g. `19 Sep 2020`
210
- */
211
- export const FMT_dMMMyyyy = defFormat(["d", "~~", "MMM", " ", "yyyy"]);
212
- /**
213
- * Format preset, e.g. `17:08`
214
- */
215
- export const FMT_HHmm = defFormat(["HH", ":", "mm"]);
216
- /**
217
- * Format preset, e.g. `5:08 PM`
218
- */
219
- export const FMT_hm = defFormat(["h", ":", "mm", " ", "A"]);
220
- /**
221
- * Format preset, e.g. `17:08:01`
222
- */
223
- export const FMT_HHmmss = defFormat(["HH", ":", "mm", ":", "ss"]);
224
- /**
225
- * Format preset, e.g. `5:08:01 PM`
226
- */
227
- export const FMT_hms = defFormat(["h", ":", "mm", ":", "ss", " ", "A"]);
228
- /**
229
- * Format preset, e.g. `20200919-170801`
230
- */
231
- // prettier-ignore
232
- export const FMT_yyyyMMdd_HHmmss = defFormat(["yyyy", "MM", "dd", "-", "HH", "mm", "ss"]);
233
- /**
234
- * ISO8601 format preset (without millisecond term), e.g.
235
- * `2020-09-19T17:08:01Z`
236
- */
237
- // prettier-ignore
238
- export const FMT_ISO_SHORT = defFormat(["yyyy", "-", "MM", "-", "dd", "T", "HH", ":", "mm", ":", "ss", "ZZ"]);
239
- /**
240
- * ISO8601 format preset (with millisecond term), e.g.
241
- * `2020-09-19T17:08:01.123Z`
242
- */
243
- // prettier-ignore
244
- export const FMT_ISO = defFormat(["yyyy", "-", "MM", "-", "dd", "T", "HH", ":", "mm", ":", "ss", ".", "SS", "ZZ"]);
245
- /**
246
- * Takes a `date` and optional reference `base` date and (also optional
247
- * `prec`ision, i.e. number of fractional digits, default: 0). Computes the
248
- * difference between given dates and returns it as formatted string.
249
- *
250
- * @remarks
251
- * Returns {@link LOCALE.now} if absolute difference is < `eps` milliseconds
252
- * (default: 100).
253
- *
254
- * @see {@link formatRelativeParts} for alternative output.
255
- *
256
- *
257
- * @example
258
- * ```ts
259
- * formatRelative("2020-06-01", "2021-07-01")
260
- * // "1 year ago"
261
- *
262
- * formatRelative("2020-08-01", "2021-07-01")
263
- * // "11 months ago"
264
- *
265
- * formatRelative("2021-07-01 13:45", "2021-07-01 12:05")
266
- * // "in 2 hours"
267
- *
268
- * formatRelative("2021-07-01 12:23:24", "2021-07-01 12:05")
269
- * // "in 18 minutes"
270
- * ```
271
- *
272
- * @param date -
273
- * @param base -
274
- * @param prec -
275
- * @param eps -
276
- */
277
- export const formatRelative = (date, base = new Date(), prec = 0, eps = 100) => {
278
- const delta = difference(date, base);
279
- if (Math.abs(delta) < eps)
280
- return LOCALE.now;
281
- let abs = Math.abs(delta);
282
- let unit;
283
- if (abs < SECOND) {
284
- unit = "t";
285
- }
286
- else if (abs < MINUTE) {
287
- abs /= SECOND;
288
- unit = "s";
289
- }
290
- else if (abs < HOUR) {
291
- abs /= MINUTE;
292
- unit = "m";
293
- }
294
- else if (abs < DAY) {
295
- abs /= HOUR;
296
- unit = "h";
297
- }
298
- else if (abs < MONTH) {
299
- abs /= DAY;
300
- unit = "d";
301
- }
302
- else if (abs < YEAR) {
303
- abs /= MONTH;
304
- unit = "M";
305
- }
306
- else {
307
- abs /= YEAR;
308
- unit = "y";
309
- }
310
- const exp = 10 ** -prec;
311
- abs = Math.round(abs / exp) * exp;
312
- return tense(delta, `${abs.toFixed(prec)} ${units(abs, unit, true, true)}`);
162
+ const FMT_yyyyMMdd = defFormat(["yyyy", "-", "MM", "-", "dd"]);
163
+ const FMT_Mdyyyy = defFormat(["M", "/", "d", "/", "yyyy"]);
164
+ const FMT_MMMdyyyy = defFormat(["MMM", " ", "d", " ", "yyyy"]);
165
+ const FMT_dMyyyy = defFormat(["d", "~", "M", "~", "yyyy"]);
166
+ const FMT_dMMMyyyy = defFormat(["d", "~~", "MMM", " ", "yyyy"]);
167
+ const FMT_HHmm = defFormat(["HH", ":", "mm"]);
168
+ const FMT_hm = defFormat(["h", ":", "mm", " ", "A"]);
169
+ const FMT_HHmmss = defFormat(["HH", ":", "mm", ":", "ss"]);
170
+ const FMT_hms = defFormat(["h", ":", "mm", ":", "ss", " ", "A"]);
171
+ const FMT_yyyyMMdd_HHmmss = defFormat(
172
+ ["yyyy", "MM", "dd", "-", "HH", "mm", "ss"]
173
+ );
174
+ const FMT_ISO_SHORT = defFormat(
175
+ ["yyyy", "-", "MM", "-", "dd", "T", "HH", ":", "mm", ":", "ss", "ZZ"]
176
+ );
177
+ const FMT_ISO = defFormat(
178
+ ["yyyy", "-", "MM", "-", "dd", "T", "HH", ":", "mm", ":", "ss", ".", "SS", "ZZ"]
179
+ );
180
+ const formatRelative = (date, base = /* @__PURE__ */ new Date(), prec = 0, eps = 100) => {
181
+ const delta = difference(date, base);
182
+ if (Math.abs(delta) < eps)
183
+ return LOCALE.now;
184
+ let abs = Math.abs(delta);
185
+ let unit;
186
+ if (abs < SECOND) {
187
+ unit = "t";
188
+ } else if (abs < MINUTE) {
189
+ abs /= SECOND;
190
+ unit = "s";
191
+ } else if (abs < HOUR) {
192
+ abs /= MINUTE;
193
+ unit = "m";
194
+ } else if (abs < DAY) {
195
+ abs /= HOUR;
196
+ unit = "h";
197
+ } else if (abs < MONTH) {
198
+ abs /= DAY;
199
+ unit = "d";
200
+ } else if (abs < YEAR) {
201
+ abs /= MONTH;
202
+ unit = "M";
203
+ } else {
204
+ abs /= YEAR;
205
+ unit = "y";
206
+ }
207
+ const exp = 10 ** -prec;
208
+ abs = Math.round(abs / exp) * exp;
209
+ return tense(delta, `${abs.toFixed(prec)} ${units(abs, unit, true, true)}`);
313
210
  };
314
- /**
315
- * Similar to {@link formatRelative}, however precision is specified as
316
- * {@link Precision} (default: seconds). The result will be formatted as a
317
- * string made up of parts of increasing precision (years, months, days, hours,
318
- * etc.). Only non-zero parts will be mentioned.
319
- *
320
- * @remarks
321
- * Returns {@link LOCALE.now} if absolute difference is < `eps` milliseconds
322
- * (default: 100). In all other cases uses {@link decomposeDifference} for
323
- * given dates to extract parts for formatting.
324
- *
325
- * @example
326
- * ```ts
327
- * // with default precision (seconds)
328
- * formatRelativeParts("2022-09-01 12:23:24", "2021-07-01 12:05")
329
- * // "in 1 year, 2 months, 21 hours, 18 minutes, 24 seconds"
330
- *
331
- * // with day precision
332
- * formatRelativeParts("2012-12-25 17:59", "2021-07-01 12:05", "d")
333
- * // "8 years, 6 months, 5 days ago"
334
- *
335
- * formatRelativeParts("2021-07-01 17:59", "2021-07-01 12:05", "d")
336
- * // "in less than a day"
337
- * ```
338
- *
339
- * @param date -
340
- * @param base -
341
- * @param prec -
342
- * @param eps -
343
- */
344
- export const formatRelativeParts = (date, base = Date.now(), prec = "s", eps = 1000) => {
345
- date = ensureEpoch(date);
346
- base = ensureEpoch(base);
347
- if (Math.abs(date - base) < eps)
348
- return LOCALE.now;
349
- const [sign, ...parts] = decomposeDifference(date, base);
350
- return tense(sign, formatDurationParts(parts, prec));
211
+ const formatRelativeParts = (date, base = Date.now(), prec = "s", eps = 1e3) => {
212
+ date = ensureEpoch(date);
213
+ base = ensureEpoch(base);
214
+ if (Math.abs(date - base) < eps)
215
+ return LOCALE.now;
216
+ const [sign, ...parts] = decomposeDifference(date, base);
217
+ return tense(sign, formatDurationParts(parts, prec));
351
218
  };
352
- /**
353
- * Formats given duration (in ms) to given precision and using current
354
- * {@link LOCALE}.
355
- *
356
- * @example
357
- * ```ts
358
- * formatDuration(45296000)
359
- * // "12 h, 34 min, 56 s"
360
- *
361
- * formatDuration(45296000, "h")
362
- * // "13 h"
363
- *
364
- * formatDuration(45296000,"d")
365
- * // "< 1 d"
366
- * ```
367
- *
368
- * @param dur
369
- * @param prec
370
- */
371
- export const formatDuration = (dur, prec = "s") => formatDurationParts(decomposeDuration(dur), prec);
372
- /**
373
- * Formats an already decomposed duration (in most case you'll want to use
374
- * {@link formatDuration}).
375
- *
376
- * @param parts
377
- * @param prec
378
- */
379
- export const formatDurationParts = (parts, prec = "s") => {
380
- const precID = __precisionToID(prec);
381
- let maxID = precID;
382
- while (!parts[maxID] && maxID > 0)
383
- maxID--;
384
- let minID = parts.findIndex((x) => x > 0);
385
- minID < 0 && (minID = maxID);
386
- maxID = Math.min(Math.max(maxID, minID), precID);
387
- if (minID <= precID && precID < 6) {
388
- parts[maxID] = Math.round(parts[maxID] + parts[maxID + 1] / [12, 31, 24, 60, 60, 1000][maxID]);
389
- }
390
- return parts
391
- .slice(0, maxID + 1)
392
- .map((x, i) => {
393
- let unit = LOCALE.units[__idToPrecision(i)];
394
- return x > 0
395
- ? units(x, unit, true)
396
- : i === maxID && maxID < 6
397
- ? unitsLessThan(1, unit, true)
398
- : "";
399
- })
400
- .filter((x) => !!x)
401
- .join(", ");
219
+ const formatDuration = (dur, prec = "s") => formatDurationParts(decomposeDuration(dur), prec);
220
+ const formatDurationParts = (parts, prec = "s") => {
221
+ const precID = __precisionToID(prec);
222
+ let maxID = precID;
223
+ while (!parts[maxID] && maxID > 0)
224
+ maxID--;
225
+ let minID = parts.findIndex((x) => x > 0);
226
+ minID < 0 && (minID = maxID);
227
+ maxID = Math.min(Math.max(maxID, minID), precID);
228
+ if (minID <= precID && precID < 6) {
229
+ parts[maxID] = Math.round(
230
+ parts[maxID] + parts[maxID + 1] / [12, 31, 24, 60, 60, 1e3][maxID]
231
+ );
232
+ }
233
+ return parts.slice(0, maxID + 1).map((x, i) => {
234
+ let unit = LOCALE.units[__idToPrecision(i)];
235
+ return x > 0 ? units(x, unit, true) : i === maxID && maxID < 6 ? unitsLessThan(1, unit, true) : "";
236
+ }).filter((x) => !!x).join(", ");
237
+ };
238
+ export {
239
+ FMT_HHmm,
240
+ FMT_HHmmss,
241
+ FMT_ISO,
242
+ FMT_ISO_SHORT,
243
+ FMT_MMMdyyyy,
244
+ FMT_Mdyyyy,
245
+ FMT_dMMMyyyy,
246
+ FMT_dMyyyy,
247
+ FMT_hm,
248
+ FMT_hms,
249
+ FMT_yyyyMMdd,
250
+ FMT_yyyyMMdd_HHmmss,
251
+ FORMATTERS,
252
+ defFormat,
253
+ formatDuration,
254
+ formatDurationParts,
255
+ formatRelative,
256
+ formatRelativeParts
402
257
  };