atomic-fns 1.1.2 → 1.1.4
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/README.md +11 -11
- package/dist/collections/index.d.ts +1 -13
- package/dist/collections/index.js +11 -21
- package/dist/functools/index.d.ts +6 -6
- package/dist/functools/index.js +19 -11
- package/dist/globals/index.d.ts +40 -40
- package/dist/globals/index.js +117 -46
- package/dist/itertools/index.d.ts +2 -2
- package/dist/itertools/index.js +4 -4
- package/dist/math/index.d.ts +2 -2
- package/dist/math/index.js +6 -2
- package/dist/operators/index.d.ts +4 -4
- package/dist/operators/index.js +11 -5
- package/dist/random/index.d.ts +2 -2
- package/dist/random/index.js +6 -2
- package/package.json +6 -3
- package/dist/globals/decimal.d.ts +0 -142
- package/dist/globals/decimal.js +0 -371
- package/dist/i18n/date/format.d.ts +0 -16
- package/dist/i18n/date/format.js +0 -313
- package/dist/i18n/date/test.html +0 -72
package/dist/globals/decimal.js
DELETED
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
const NUMBER_REGEX = /^(-?)([0-9]+)(\.([0-9]+))?$/;
|
|
2
|
-
/**
|
|
3
|
-
* Casts the given value as a {@link Decimal}.
|
|
4
|
-
*/
|
|
5
|
-
export function decimal(x) {
|
|
6
|
-
return new Decimal(x);
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* `Decimal` provides support for correct rounded floating point arithmetic, unlike the standard Number type. It also supports user-defined precision (default is 20 decimal places) which can be as large as needed.
|
|
10
|
-
*/
|
|
11
|
-
export class Decimal {
|
|
12
|
-
static PRECISION = 20;
|
|
13
|
-
i = 0n;
|
|
14
|
-
e = 0;
|
|
15
|
-
/**
|
|
16
|
-
* Returns a new `Decimal` instance from the value or `0`.
|
|
17
|
-
* @param {*} value
|
|
18
|
-
* @returns {Decimal}
|
|
19
|
-
*/
|
|
20
|
-
constructor(value) {
|
|
21
|
-
if (value == null) {
|
|
22
|
-
return this;
|
|
23
|
-
}
|
|
24
|
-
// Check if value is a Decimal like
|
|
25
|
-
if (typeof value?.i === 'bigint' && typeof value.e === 'number') {
|
|
26
|
-
this.i = value.i;
|
|
27
|
-
this.e = value.e;
|
|
28
|
-
this._normalize();
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
const result = NUMBER_REGEX.exec(value.toString());
|
|
32
|
-
if (result) {
|
|
33
|
-
// console.log(result);
|
|
34
|
-
// Construct from string if possible
|
|
35
|
-
// this.i = parseInt(result[1] + result[2] + result[4]);
|
|
36
|
-
if (typeof result[2] === 'undefined')
|
|
37
|
-
result[2] = '';
|
|
38
|
-
if (typeof result[4] === 'undefined')
|
|
39
|
-
result[4] = '';
|
|
40
|
-
this.i = BigInt(result[1] + result[2] + result[4]);
|
|
41
|
-
this.e = result[4] ? -result[4].length : 0;
|
|
42
|
-
this._normalize();
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
// Conversion to string failed, so construct from number
|
|
46
|
-
let m = 1n;
|
|
47
|
-
if (value < 0) {
|
|
48
|
-
value = -value;
|
|
49
|
-
m = -1n;
|
|
50
|
-
}
|
|
51
|
-
if (value === 0) {
|
|
52
|
-
this.i = 0n;
|
|
53
|
-
this.e = 0;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
// Multiply the number by 10 until it is an integer
|
|
57
|
-
let e = -Math.floor(Math.log10(value));
|
|
58
|
-
if (e > 0) {
|
|
59
|
-
value *= Math.pow(10, e);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
e = 0;
|
|
63
|
-
}
|
|
64
|
-
while (value !== Math.round(value)) {
|
|
65
|
-
e++;
|
|
66
|
-
value *= 10;
|
|
67
|
-
}
|
|
68
|
-
// Divide the number by 10 until the one's digit is non-zero
|
|
69
|
-
while (value % 10 === 0 && value > 0) {
|
|
70
|
-
e--;
|
|
71
|
-
value /= 10;
|
|
72
|
-
}
|
|
73
|
-
value = BigInt(value);
|
|
74
|
-
this.i = value * m;
|
|
75
|
-
this.e = -e;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Returns a new `Decimal` that has the opposite sign of this `Decimal`.
|
|
81
|
-
* @example
|
|
82
|
-
```js
|
|
83
|
-
let a = decimal('5')
|
|
84
|
-
a.minus() // -5
|
|
85
|
-
```
|
|
86
|
-
* @returns {Decimal}
|
|
87
|
-
*/
|
|
88
|
-
negated() {
|
|
89
|
-
const negated = new Decimal();
|
|
90
|
-
negated.i = -this.i;
|
|
91
|
-
negated.e = this.e;
|
|
92
|
-
return negated;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Returns a new `Decimal` that is the sum of this and `x`.
|
|
96
|
-
* @param x
|
|
97
|
-
* @example
|
|
98
|
-
```js
|
|
99
|
-
let a = decimal('50000000000')
|
|
100
|
-
let b = decimal('0.000000005')
|
|
101
|
-
a.add(b) // 50000000000.000000005
|
|
102
|
-
```
|
|
103
|
-
* @returns {Decimal}
|
|
104
|
-
*/
|
|
105
|
-
add(x) {
|
|
106
|
-
let a = new Decimal(this);
|
|
107
|
-
let b = new Decimal(x);
|
|
108
|
-
// a+b = a.i * 10^a.e + b.i * 10^b.e
|
|
109
|
-
// a+b = ( a.i * 10^(a.e-b.e) + b.i ) * 10^b.e
|
|
110
|
-
const result = new Decimal();
|
|
111
|
-
// Order arguments so that a.e >= b.e
|
|
112
|
-
if (a.e < b.e) {
|
|
113
|
-
const c = a;
|
|
114
|
-
a = b;
|
|
115
|
-
b = c;
|
|
116
|
-
}
|
|
117
|
-
const intPart = exp(a.i, a.e - b.e);
|
|
118
|
-
result.i = intPart + b.i;
|
|
119
|
-
result.e = b.e;
|
|
120
|
-
result._normalize();
|
|
121
|
-
return result;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Returns a new `Decimal` that is the difference between this and `x`.
|
|
125
|
-
* @param x
|
|
126
|
-
* @example
|
|
127
|
-
```js
|
|
128
|
-
let a = decimal('1')
|
|
129
|
-
let b = decimal('0.0000000000000000001')
|
|
130
|
-
a.sub(b) // 0.9999999999999999999
|
|
131
|
-
```
|
|
132
|
-
* @returns {Decimal}
|
|
133
|
-
*/
|
|
134
|
-
sub(x) {
|
|
135
|
-
return this.add(decimal(x).negated());
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Returns a new `Decimal` that is the product of this and `x`.
|
|
139
|
-
* @param x
|
|
140
|
-
* @example
|
|
141
|
-
```js
|
|
142
|
-
let a = decimal('0.0000000000000000000025')
|
|
143
|
-
let b = decimal('400000000000000000000')
|
|
144
|
-
a.mul(b) // 1
|
|
145
|
-
```
|
|
146
|
-
* @returns {Decimal}
|
|
147
|
-
*/
|
|
148
|
-
mul(x) {
|
|
149
|
-
const a = new Decimal(this);
|
|
150
|
-
const b = new Decimal(x);
|
|
151
|
-
// a * b = (a.i * b.i) * 10^(a.e + b.e)
|
|
152
|
-
const result = new Decimal();
|
|
153
|
-
result.i = a.i * b.i;
|
|
154
|
-
result.e = a.e + b.e;
|
|
155
|
-
result._normalize();
|
|
156
|
-
return result;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Returns a new `Decimal` that is the quotient of this and `x`
|
|
160
|
-
* @param x
|
|
161
|
-
* @example
|
|
162
|
-
```js
|
|
163
|
-
let a = decimal('1')
|
|
164
|
-
let b = decimal('3')
|
|
165
|
-
a.div(b) // 0.333333333333333333333333333333
|
|
166
|
-
```
|
|
167
|
-
* @returns {Decimal}
|
|
168
|
-
*/
|
|
169
|
-
div(x) {
|
|
170
|
-
const a = new Decimal(this);
|
|
171
|
-
const b = new Decimal(x);
|
|
172
|
-
// We need to increase the number of digits of a and b so that a / b will have the desired precision.
|
|
173
|
-
// In order for the integer quotient to have the correct precision, a.e - b.e must be greater than that precision.
|
|
174
|
-
// So we need only to increase a.e.
|
|
175
|
-
// TODO: Revisit the value of increaseA. Is it correct in every circumstance?
|
|
176
|
-
const increaseA = Math.max(Decimal.precision - (a.e + b.e), 0);
|
|
177
|
-
const intIncrease = new Decimal();
|
|
178
|
-
intIncrease.i = exp(a.i, increaseA);
|
|
179
|
-
const quotient = new Decimal();
|
|
180
|
-
quotient.i = intIncrease.i / b.i;
|
|
181
|
-
quotient.e = a.e - b.e - increaseA;
|
|
182
|
-
// No need to truncate since we already increased the number of digits before dividing
|
|
183
|
-
quotient._normalize();
|
|
184
|
-
return quotient;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Returns the square root of this `Decimal`.
|
|
188
|
-
* @returns {TDecimal}
|
|
189
|
-
*/
|
|
190
|
-
sqrt() {
|
|
191
|
-
Decimal.PRECISION++;
|
|
192
|
-
// Let the guess value be 10^(e/2), where e is this.e
|
|
193
|
-
let x = new Decimal();
|
|
194
|
-
x.i = 1n;
|
|
195
|
-
x.e = Math.floor(this.e / 2);
|
|
196
|
-
const onehalf = new Decimal('0.5');
|
|
197
|
-
let xt = x.clone();
|
|
198
|
-
xt._truncate();
|
|
199
|
-
xt._normalize();
|
|
200
|
-
let lastxt;
|
|
201
|
-
let i;
|
|
202
|
-
for (i = 0; i < 100; i++) {
|
|
203
|
-
lastxt = xt;
|
|
204
|
-
x = this.div(x).add(x).mul(onehalf);
|
|
205
|
-
xt = x.clone();
|
|
206
|
-
xt._truncate();
|
|
207
|
-
xt._normalize();
|
|
208
|
-
if (xt.i === lastxt.i && xt.e === lastxt.e)
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
if (i >= 100) {
|
|
212
|
-
console.log('Warning: sqrt exceeded maximum iterations. (Did it enter a cycle?)');
|
|
213
|
-
}
|
|
214
|
-
Decimal.PRECISION--;
|
|
215
|
-
xt._truncate();
|
|
216
|
-
xt._normalize();
|
|
217
|
-
return xt;
|
|
218
|
-
}
|
|
219
|
-
/** Returns a new copy of this Decimal value. */
|
|
220
|
-
clone() {
|
|
221
|
-
const a = new Decimal();
|
|
222
|
-
a.i = this.i;
|
|
223
|
-
a.e = this.e;
|
|
224
|
-
return a;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Remove zeroes in the least-significant digit of this `Decimal`
|
|
228
|
-
*/
|
|
229
|
-
_normalize() {
|
|
230
|
-
while (this.i % 10n === 0n && this.i !== 0n) {
|
|
231
|
-
this.i /= 10n;
|
|
232
|
-
this.e++;
|
|
233
|
-
}
|
|
234
|
-
return this;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Truncate this `Decimal` to the configured precision
|
|
238
|
-
*/
|
|
239
|
-
_truncate() {
|
|
240
|
-
// TODO: Make this better
|
|
241
|
-
// TODO: Rounding
|
|
242
|
-
const trunc = -this.e - Decimal.PRECISION;
|
|
243
|
-
if (trunc > 0) {
|
|
244
|
-
this.i /= 10n ** BigInt(trunc - 1);
|
|
245
|
-
this.e += trunc;
|
|
246
|
-
const nextDigit = this.i % 10n;
|
|
247
|
-
if (nextDigit >= 5) {
|
|
248
|
-
this.i += 10n;
|
|
249
|
-
}
|
|
250
|
-
this.i /= 10n;
|
|
251
|
-
}
|
|
252
|
-
// while(-this.e > Decimal.PRECISION) {
|
|
253
|
-
// this.i /= 10n;
|
|
254
|
-
// this.e++;
|
|
255
|
-
// }
|
|
256
|
-
return this;
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Returns a string representation of this decimal.
|
|
260
|
-
* @returns {Decimal}
|
|
261
|
-
*/
|
|
262
|
-
toString() {
|
|
263
|
-
let s = this.i.toString();
|
|
264
|
-
let m = '';
|
|
265
|
-
if (s[0] === '-') {
|
|
266
|
-
s = s.substring(1, s.length);
|
|
267
|
-
m = '-';
|
|
268
|
-
}
|
|
269
|
-
if (this.e > 0) {
|
|
270
|
-
return m + s + '0'.repeat(this.e);
|
|
271
|
-
}
|
|
272
|
-
else if (this.e < 0) {
|
|
273
|
-
if (-this.e >= s.length) {
|
|
274
|
-
return m + '0.' + '0'.repeat(-this.e - s.length) + s;
|
|
275
|
-
}
|
|
276
|
-
return m + s.slice(0, s.length + this.e) + '.' + s.slice(s.length + this.e, s.length);
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
return m + s;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
283
|
-
return this.toString();
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Converts this decimal to the `Number` value
|
|
287
|
-
* @returns {number}
|
|
288
|
-
*/
|
|
289
|
-
toNumber() {
|
|
290
|
-
return Number(Decimal.prototype.toString.call(this));
|
|
291
|
-
}
|
|
292
|
-
static get precision() {
|
|
293
|
-
return Decimal.PRECISION;
|
|
294
|
-
}
|
|
295
|
-
static set precision(value) {
|
|
296
|
-
Decimal.PRECISION = value;
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Returns `true` if this value is equal to the value of `x`, otherwise `false`.
|
|
300
|
-
* @param {*} x other
|
|
301
|
-
* @returns {boolean}
|
|
302
|
-
*/
|
|
303
|
-
eq(x) {
|
|
304
|
-
const other = decimal(x);
|
|
305
|
-
return this.i === other.i && this.e === other.e;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Returns `true` if this value is less than the value of `x`, otherwise `false`.
|
|
309
|
-
* @param {*} x
|
|
310
|
-
* @returns {boolean}
|
|
311
|
-
*/
|
|
312
|
-
lt(x) {
|
|
313
|
-
const other = decimal(x);
|
|
314
|
-
if (this.e === other.e)
|
|
315
|
-
return this.i < other.i;
|
|
316
|
-
const e = this.e - other.e;
|
|
317
|
-
if (e > 0) {
|
|
318
|
-
return exp(this.i, e) < other.i;
|
|
319
|
-
}
|
|
320
|
-
return this.i < exp(other.i, -e);
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Returns a comparison value representing the ordering of this value in respect to `x`.
|
|
324
|
-
* * `-1` if this < x
|
|
325
|
-
* * `1` if this > x
|
|
326
|
-
* * `0` if this == x
|
|
327
|
-
* @param {*} x
|
|
328
|
-
* @returns {number}
|
|
329
|
-
*/
|
|
330
|
-
compare(x) {
|
|
331
|
-
if (this.eq(x))
|
|
332
|
-
return 0;
|
|
333
|
-
if (this.lt(x))
|
|
334
|
-
return -1;
|
|
335
|
-
return 1;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Returns `true` if this value is greater than the value of `x`, otherwise `false`.
|
|
339
|
-
* @param {*} x
|
|
340
|
-
* @returns {boolean}
|
|
341
|
-
*/
|
|
342
|
-
gt(x) {
|
|
343
|
-
return this.compare(x) > 0;
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Returns `true` if this value is less than or equal to the value of `x`, otherwise `false`.
|
|
347
|
-
* @param {*} x
|
|
348
|
-
* @returns {boolean}
|
|
349
|
-
*/
|
|
350
|
-
lte(x) {
|
|
351
|
-
return this.compare(x) <= 0;
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Returns `true` if this value is greater than or equal to the value of `x`, otherwise `false`.
|
|
355
|
-
* @param {*} x
|
|
356
|
-
* @returns {boolean}
|
|
357
|
-
*/
|
|
358
|
-
gte(x) {
|
|
359
|
-
return this.compare(x) >= 0;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
/** Returns a BigInt that is equal to `i` times `10^e` */
|
|
363
|
-
function exp(i, e) {
|
|
364
|
-
// TODO: Make this better
|
|
365
|
-
// The implementation is faster than 10n ** BigInt(e). But could we make it faster still?
|
|
366
|
-
let ii = i;
|
|
367
|
-
for (let j = 0; j < e; j++) {
|
|
368
|
-
ii *= 10n;
|
|
369
|
-
}
|
|
370
|
-
return ii;
|
|
371
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a new Date from the given arguments.
|
|
3
|
-
* @param {string | number | Date} date The date value
|
|
4
|
-
* @param {?boolean} [utc=false] Interprets the given value as a UTC date
|
|
5
|
-
* @returns {Date} The new date object
|
|
6
|
-
*/
|
|
7
|
-
export declare function getDate(date: string | number | Date, utc?: boolean): Date;
|
|
8
|
-
/**
|
|
9
|
-
* Formats a date using a formatting string in the {@link https://strftime.org/ strftime} format, in any given locale.
|
|
10
|
-
* @param {string} fmt The format string to apply
|
|
11
|
-
* @param {number | Date} date The date value
|
|
12
|
-
* @param {?string} locale The locale to use when formatting (default is system locale).
|
|
13
|
-
* @returns {string} The string representation of date
|
|
14
|
-
* @see {@link https://strftime.org/ strftime format}
|
|
15
|
-
*/
|
|
16
|
-
export declare function format(fmt: string, date: number | Date, locale?: any): string;
|
package/dist/i18n/date/format.js
DELETED
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
const NATIVE_DATE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/;
|
|
2
|
-
/**
|
|
3
|
-
* Returns a new Date from the given arguments.
|
|
4
|
-
* @param {string | number | Date} date The date value
|
|
5
|
-
* @param {?boolean} [utc=false] Interprets the given value as a UTC date
|
|
6
|
-
* @returns {Date} The new date object
|
|
7
|
-
*/
|
|
8
|
-
export function getDate(date, utc = false) {
|
|
9
|
-
if (date === null)
|
|
10
|
-
return new Date(NaN);
|
|
11
|
-
if (!date)
|
|
12
|
-
return new Date();
|
|
13
|
-
if (date instanceof Date)
|
|
14
|
-
return new Date(date);
|
|
15
|
-
if (typeof date === 'string' && !/Z$/i.test(date)) {
|
|
16
|
-
const d = date.match(NATIVE_DATE);
|
|
17
|
-
if (d) {
|
|
18
|
-
const m = d[2] - 1 || 0;
|
|
19
|
-
const ms = (d[7] || '0').slice(0, 3);
|
|
20
|
-
if (utc) {
|
|
21
|
-
return new Date(Date.UTC(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms));
|
|
22
|
-
}
|
|
23
|
-
return new Date(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return new Date(date);
|
|
27
|
-
}
|
|
28
|
-
const n = 'numeric';
|
|
29
|
-
const s = 'short';
|
|
30
|
-
const l = 'long';
|
|
31
|
-
const dd = '2-digit';
|
|
32
|
-
const TOKEN_MAP = {
|
|
33
|
-
// weekday
|
|
34
|
-
'%A': { weekday: l },
|
|
35
|
-
'%a': { weekday: s },
|
|
36
|
-
'%aa': { weekday: n },
|
|
37
|
-
// day
|
|
38
|
-
'%d': { day: dd },
|
|
39
|
-
'%-d': { day: n },
|
|
40
|
-
// month
|
|
41
|
-
'%m': { month: dd },
|
|
42
|
-
'%-m': { month: n },
|
|
43
|
-
'%B': { month: l },
|
|
44
|
-
'%b': { month: s },
|
|
45
|
-
'%bb': { month: n },
|
|
46
|
-
// year
|
|
47
|
-
'%y': { year: n },
|
|
48
|
-
'%Y': { year: dd },
|
|
49
|
-
// hour
|
|
50
|
-
'%K': { hourCycle: 'h11', hour: dd },
|
|
51
|
-
'%I': { hourCycle: 'h12', hour: dd },
|
|
52
|
-
'%-I': { hourCycle: 'h12', hour: n },
|
|
53
|
-
'%H': { hourCycle: 'h23', hour: dd },
|
|
54
|
-
'%-H': { hourCycle: 'h23', hour: n },
|
|
55
|
-
'%k': { hourCycle: 'h24', hour: n },
|
|
56
|
-
// minutes
|
|
57
|
-
'%M': { minute: dd },
|
|
58
|
-
'%-M': { minute: n },
|
|
59
|
-
// seconds
|
|
60
|
-
'%S': { second: dd },
|
|
61
|
-
'%-S': { second: n },
|
|
62
|
-
// day period
|
|
63
|
-
'%P': { dayPeriod: l },
|
|
64
|
-
'%p': { dayPeriod: s },
|
|
65
|
-
'%pp': { dayPeriod: 'narrow' },
|
|
66
|
-
// era
|
|
67
|
-
'%N': { era: l, year: dd },
|
|
68
|
-
'%n': { era: s, year: dd },
|
|
69
|
-
'%nn': { era: n, year: 'narrow' },
|
|
70
|
-
// timeZoneName
|
|
71
|
-
'%Z': { timeZoneName: 'longGeneric', year: dd },
|
|
72
|
-
'%-Z': { timeZoneName: 'shortGeneric', year: dd },
|
|
73
|
-
'%z': { timeZoneName: 'longOffset', year: dd },
|
|
74
|
-
'%-z': { timeZoneName: 'shortOffset', year: dd },
|
|
75
|
-
'%ZZ': { timeZoneName: l, year: dd },
|
|
76
|
-
'%-ZZ': { timeZoneName: s, year: dd }
|
|
77
|
-
};
|
|
78
|
-
const HOUR_PARTS = { '%I': 1, '%-I': 1, '%K': 1, '%k': 1 };
|
|
79
|
-
const ERA_PARTS = { '%n': 1, '%N': 1, '%nn': 1 };
|
|
80
|
-
const TZ_PARTS = { '%ZZ': 1, '%-ZZ': 1, '%-z': 1, '%z': 1, '%-Z': 1, '%Z': 1 };
|
|
81
|
-
const formatter = (locale, opts) => new Intl.DateTimeFormat(locale, opts);
|
|
82
|
-
/**
|
|
83
|
-
* Formats a date using a formatting string in the {@link https://strftime.org/ strftime} format, in any given locale.
|
|
84
|
-
* @param {string} fmt The format string to apply
|
|
85
|
-
* @param {number | Date} date The date value
|
|
86
|
-
* @param {?string} locale The locale to use when formatting (default is system locale).
|
|
87
|
-
* @returns {string} The string representation of date
|
|
88
|
-
* @see {@link https://strftime.org/ strftime format}
|
|
89
|
-
*/
|
|
90
|
-
export function format(fmt, date, locale) {
|
|
91
|
-
const results = [];
|
|
92
|
-
let dayPeriod = '';
|
|
93
|
-
let dayPeriodIndex = -1;
|
|
94
|
-
for (let i = 0; i < fmt.length; i++) {
|
|
95
|
-
let part = fmt[i];
|
|
96
|
-
if (part === '%') {
|
|
97
|
-
// check for escaped '%'
|
|
98
|
-
if (fmt[++i] === '%') {
|
|
99
|
-
results.push('%');
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (fmt[i] === '-') {
|
|
103
|
-
part += fmt[i++];
|
|
104
|
-
}
|
|
105
|
-
part += fmt[i];
|
|
106
|
-
// add any repeated characters that come after
|
|
107
|
-
while (i < fmt.length - 1 && fmt[i + 1] === fmt[i])
|
|
108
|
-
part += fmt[++i];
|
|
109
|
-
if (HOUR_PARTS[part]) {
|
|
110
|
-
const res = formatter(locale, TOKEN_MAP[part]).format(date).split(' ');
|
|
111
|
-
// save the AM/PM for the correct spot
|
|
112
|
-
results.push(res[0]);
|
|
113
|
-
dayPeriod = res[1];
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
if (part === '%P' || part === '%p') {
|
|
117
|
-
// leave this flag in place for later
|
|
118
|
-
dayPeriodIndex = results.length;
|
|
119
|
-
results.push(part);
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (ERA_PARTS[part] || TZ_PARTS[part]) {
|
|
123
|
-
// the formatting includes the date/year so we take what comes after
|
|
124
|
-
const res = formatter(locale, TOKEN_MAP[part]).format(date).split(' ');
|
|
125
|
-
results.push(res.slice(1).join(' '));
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
// format any other parts
|
|
129
|
-
let res = formatter(locale, TOKEN_MAP[part]).format(date);
|
|
130
|
-
if (part === '%S' && res.length === 1)
|
|
131
|
-
res = '0' + res;
|
|
132
|
-
results.push(res);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
// output as literal
|
|
136
|
-
results.push(part);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// insert the AM/PM at the correct spot
|
|
140
|
-
if (dayPeriodIndex >= 0)
|
|
141
|
-
results[dayPeriodIndex] = dayPeriod || '';
|
|
142
|
-
return results.join('');
|
|
143
|
-
}
|
|
144
|
-
const DATETIME_DEFAULT = {};
|
|
145
|
-
/** 10/14/1983 */
|
|
146
|
-
const DATE_SHORT = {
|
|
147
|
-
year: n,
|
|
148
|
-
month: n,
|
|
149
|
-
day: n
|
|
150
|
-
};
|
|
151
|
-
/** Oct 14, 1983 */
|
|
152
|
-
const DATE_MED = {
|
|
153
|
-
year: n,
|
|
154
|
-
month: s,
|
|
155
|
-
day: n
|
|
156
|
-
};
|
|
157
|
-
/** Fri, Oct 14, 1983 */
|
|
158
|
-
const DATE_MED_WITH_WEEKDAY = {
|
|
159
|
-
year: n,
|
|
160
|
-
month: s,
|
|
161
|
-
day: n,
|
|
162
|
-
weekday: s
|
|
163
|
-
};
|
|
164
|
-
/** October 14, 1983 */
|
|
165
|
-
const DATE_FULL = {
|
|
166
|
-
year: n,
|
|
167
|
-
month: l,
|
|
168
|
-
day: n
|
|
169
|
-
};
|
|
170
|
-
/** Tuesday, October 14, 1983 */
|
|
171
|
-
const DATE_HUGE = {
|
|
172
|
-
year: n,
|
|
173
|
-
month: l,
|
|
174
|
-
day: n,
|
|
175
|
-
weekday: l
|
|
176
|
-
};
|
|
177
|
-
/** 09:30 AM */
|
|
178
|
-
const TIME_SIMPLE = {
|
|
179
|
-
hour: n,
|
|
180
|
-
minute: n
|
|
181
|
-
};
|
|
182
|
-
/** 09:30:23 AM */
|
|
183
|
-
const TIME_WITH_SECONDS = {
|
|
184
|
-
hour: n,
|
|
185
|
-
minute: n,
|
|
186
|
-
second: n
|
|
187
|
-
};
|
|
188
|
-
/** 09:30:23 AM EDT */
|
|
189
|
-
const TIME_WITH_SHORT_OFFSET = {
|
|
190
|
-
hour: n,
|
|
191
|
-
minute: n,
|
|
192
|
-
second: n,
|
|
193
|
-
timeZoneName: s
|
|
194
|
-
};
|
|
195
|
-
/** 09:30:23 AM Eastern Daylight Time */
|
|
196
|
-
const TIME_WITH_LONG_OFFSET = {
|
|
197
|
-
hour: n,
|
|
198
|
-
minute: n,
|
|
199
|
-
second: n,
|
|
200
|
-
timeZoneName: l
|
|
201
|
-
};
|
|
202
|
-
/** 09:30 */
|
|
203
|
-
const TIME_24_SIMPLE = {
|
|
204
|
-
hour: n,
|
|
205
|
-
minute: n,
|
|
206
|
-
hourCycle: 'h23'
|
|
207
|
-
};
|
|
208
|
-
/** 09:30:23 */
|
|
209
|
-
const TIME_24_WITH_SECONDS = {
|
|
210
|
-
hour: n,
|
|
211
|
-
minute: n,
|
|
212
|
-
second: n,
|
|
213
|
-
hourCycle: 'h23'
|
|
214
|
-
};
|
|
215
|
-
/** 09:30:23 EDT */
|
|
216
|
-
const TIME_24_WITH_SHORT_OFFSET = {
|
|
217
|
-
hour: n,
|
|
218
|
-
minute: n,
|
|
219
|
-
second: n,
|
|
220
|
-
hourCycle: 'h23',
|
|
221
|
-
timeZoneName: s
|
|
222
|
-
};
|
|
223
|
-
/** 09:30:23 Eastern Daylight Time */
|
|
224
|
-
const TIME_24_WITH_LONG_OFFSET = {
|
|
225
|
-
hour: n,
|
|
226
|
-
minute: n,
|
|
227
|
-
second: n,
|
|
228
|
-
hourCycle: 'h23',
|
|
229
|
-
timeZoneName: l
|
|
230
|
-
};
|
|
231
|
-
/** 10/14/1983, 9:30 AM */
|
|
232
|
-
const DATETIME_SHORT = {
|
|
233
|
-
year: n,
|
|
234
|
-
month: n,
|
|
235
|
-
day: n,
|
|
236
|
-
hour: n,
|
|
237
|
-
minute: n
|
|
238
|
-
};
|
|
239
|
-
/** 10/14/1983, 9:30:33 AM */
|
|
240
|
-
const DATETIME_SHORT_WITH_SECONDS = {
|
|
241
|
-
year: n,
|
|
242
|
-
month: n,
|
|
243
|
-
day: n,
|
|
244
|
-
hour: n,
|
|
245
|
-
minute: n,
|
|
246
|
-
second: n
|
|
247
|
-
};
|
|
248
|
-
/** Oct 14, 1983, 9:30 AM */
|
|
249
|
-
const DATETIME_MED = {
|
|
250
|
-
year: n,
|
|
251
|
-
month: s,
|
|
252
|
-
day: n,
|
|
253
|
-
hour: n,
|
|
254
|
-
minute: n
|
|
255
|
-
};
|
|
256
|
-
/** Oct 14, 1983, 9:30:33 AM */
|
|
257
|
-
const DATETIME_MED_WITH_SECONDS = {
|
|
258
|
-
year: n,
|
|
259
|
-
month: s,
|
|
260
|
-
day: n,
|
|
261
|
-
hour: n,
|
|
262
|
-
minute: n,
|
|
263
|
-
second: n
|
|
264
|
-
};
|
|
265
|
-
/** Fri, 14 Oct 1983, 9:30 AM */
|
|
266
|
-
const DATETIME_MED_WITH_WEEKDAY = {
|
|
267
|
-
year: n,
|
|
268
|
-
month: s,
|
|
269
|
-
day: n,
|
|
270
|
-
weekday: s,
|
|
271
|
-
hour: n,
|
|
272
|
-
minute: n
|
|
273
|
-
};
|
|
274
|
-
/** October 14, 1983, 9:30 AM EDT */
|
|
275
|
-
const DATETIME_FULL = {
|
|
276
|
-
year: n,
|
|
277
|
-
month: l,
|
|
278
|
-
day: n,
|
|
279
|
-
hour: n,
|
|
280
|
-
minute: n,
|
|
281
|
-
timeZoneName: s
|
|
282
|
-
};
|
|
283
|
-
/** October 14, 1983, 9:30:33 AM EDT */
|
|
284
|
-
const DATETIME_FULL_WITH_SECONDS = {
|
|
285
|
-
year: n,
|
|
286
|
-
month: l,
|
|
287
|
-
day: n,
|
|
288
|
-
hour: n,
|
|
289
|
-
minute: n,
|
|
290
|
-
second: n,
|
|
291
|
-
timeZoneName: s
|
|
292
|
-
};
|
|
293
|
-
/** Friday, October 14, 1983, 9:30 AM Eastern Daylight Time */
|
|
294
|
-
const DATETIME_HUGE = {
|
|
295
|
-
year: n,
|
|
296
|
-
month: l,
|
|
297
|
-
day: n,
|
|
298
|
-
weekday: l,
|
|
299
|
-
hour: n,
|
|
300
|
-
minute: n,
|
|
301
|
-
timeZoneName: l
|
|
302
|
-
};
|
|
303
|
-
/** Friday, October 14, 1983, 9:30:33 AM Eastern Daylight Time */
|
|
304
|
-
const DATETIME_HUGE_WITH_SECONDS = {
|
|
305
|
-
year: n,
|
|
306
|
-
month: l,
|
|
307
|
-
day: n,
|
|
308
|
-
weekday: l,
|
|
309
|
-
hour: n,
|
|
310
|
-
minute: n,
|
|
311
|
-
second: n,
|
|
312
|
-
timeZoneName: l
|
|
313
|
-
};
|