@thi.ng/date 2.5.4 → 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/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/api.js +45 -55
- package/checks.js +8 -17
- package/datetime.js +318 -321
- package/duration.js +53 -97
- package/format.js +243 -388
- package/i18n/de.js +77 -81
- package/i18n/en.js +77 -81
- package/i18n/es.js +42 -43
- package/i18n/fr.js +44 -45
- package/i18n/it.js +44 -45
- package/i18n.js +47 -118
- package/internal/precision.js +6 -16
- package/iterators.js +41 -93
- package/package.json +9 -7
- package/relative.js +108 -168
- package/round.js +77 -124
- package/timecode.js +19 -43
- package/units.js +21 -16
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 {
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
export
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
};
|