@naturalcycles/js-lib 14.231.0 → 14.233.0
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/datetime/dateInterval.d.ts +1 -2
- package/dist/datetime/dateInterval.js +5 -5
- package/dist/datetime/localDate.d.ts +125 -52
- package/dist/datetime/localDate.js +259 -201
- package/dist/datetime/localTime.d.ts +50 -46
- package/dist/datetime/localTime.js +187 -195
- package/dist/datetime/timeInterval.d.ts +1 -2
- package/dist/datetime/timeInterval.js +4 -4
- package/dist/env/buildInfo.js +1 -1
- package/dist-esm/datetime/dateInterval.js +6 -6
- package/dist-esm/datetime/localDate.js +259 -195
- package/dist-esm/datetime/localTime.js +183 -190
- package/dist-esm/datetime/timeInterval.js +5 -5
- package/dist-esm/env/buildInfo.js +2 -2
- package/package.json +4 -4
- package/src/datetime/dateInterval.ts +6 -7
- package/src/datetime/localDate.ts +307 -237
- package/src/datetime/localTime.ts +209 -210
- package/src/datetime/timeInterval.ts +6 -7
- package/src/env/buildInfo.ts +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _assert } from '../error/assert';
|
|
2
2
|
import { _ms } from '../time/time.util';
|
|
3
|
-
import {
|
|
3
|
+
import { localDate } from './localDate';
|
|
4
4
|
export var ISODayOfWeek;
|
|
5
5
|
(function (ISODayOfWeek) {
|
|
6
6
|
ISODayOfWeek[ISODayOfWeek["MONDAY"] = 1] = "MONDAY";
|
|
@@ -17,100 +17,23 @@ const SECONDS_IN_DAY = 86400;
|
|
|
17
17
|
// const MILLISECONDS_IN_DAY = 86400000
|
|
18
18
|
// const MILLISECONDS_IN_MINUTE = 60000
|
|
19
19
|
const VALID_DAYS_OF_WEEK = new Set([1, 2, 3, 4, 5, 6, 7]);
|
|
20
|
-
/**
|
|
21
|
-
* @experimental
|
|
22
|
-
*/
|
|
23
20
|
export class LocalTime {
|
|
24
21
|
constructor($date) {
|
|
25
22
|
this.$date = $date;
|
|
26
23
|
}
|
|
27
24
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
25
|
+
* Returns [cloned] LocalTime that is based on the same unixtimestamp, but in UTC timezone.
|
|
26
|
+
* Opposite of `.local()` method.
|
|
30
27
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
_assert(t !== null, `Cannot parse "${d}" into LocalTime`, {
|
|
34
|
-
input: d,
|
|
35
|
-
});
|
|
36
|
-
return t;
|
|
28
|
+
utc() {
|
|
29
|
+
return new LocalTime(new Date(this.$date.toISOString()));
|
|
37
30
|
}
|
|
38
31
|
/**
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
static ofMillis(millis) {
|
|
42
|
-
return LocalTime.of(new Date(millis));
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Returns null if invalid
|
|
32
|
+
* Returns [cloned] LocalTime that is based on the same unixtimestamp, but in local timezone.
|
|
33
|
+
* Opposite of `.utc()` method.
|
|
46
34
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return null;
|
|
50
|
-
if (d instanceof LocalTime)
|
|
51
|
-
return d;
|
|
52
|
-
let date;
|
|
53
|
-
if (d instanceof Date) {
|
|
54
|
-
date = d;
|
|
55
|
-
}
|
|
56
|
-
else if (typeof d === 'number') {
|
|
57
|
-
date = new Date(d * 1000);
|
|
58
|
-
}
|
|
59
|
-
else if (typeof d !== 'string') {
|
|
60
|
-
// unexpected type, e.g Function or something
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
// Slicing removes the "timezone component", and makes the date "local"
|
|
65
|
-
// e.g 2022-04-06T23:15:00+09:00
|
|
66
|
-
// becomes 2022-04-06T23:15:00
|
|
67
|
-
date = new Date(d.slice(0, 19));
|
|
68
|
-
// We used to slice to remove the timezone information, now we don't
|
|
69
|
-
// date = new Date(d)
|
|
70
|
-
}
|
|
71
|
-
// validation
|
|
72
|
-
if (isNaN(date.getDate())) {
|
|
73
|
-
// throw new TypeError(`Cannot parse "${d}" into LocalTime`)
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
// if (utc) {
|
|
77
|
-
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
78
|
-
// }
|
|
79
|
-
return new LocalTime(date);
|
|
80
|
-
}
|
|
81
|
-
static parseToDate(d) {
|
|
82
|
-
if (d instanceof LocalTime)
|
|
83
|
-
return d.$date;
|
|
84
|
-
if (d instanceof Date)
|
|
85
|
-
return d;
|
|
86
|
-
const date = typeof d === 'number' ? new Date(d * 1000) : new Date(d);
|
|
87
|
-
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to Date`, {
|
|
88
|
-
input: d,
|
|
89
|
-
});
|
|
90
|
-
return date;
|
|
91
|
-
}
|
|
92
|
-
static parseToUnixTimestamp(d) {
|
|
93
|
-
if (typeof d === 'number')
|
|
94
|
-
return d;
|
|
95
|
-
if (d instanceof LocalTime)
|
|
96
|
-
return d.unix();
|
|
97
|
-
const date = d instanceof Date ? d : new Date(d);
|
|
98
|
-
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to UnixTimestamp`, {
|
|
99
|
-
input: d,
|
|
100
|
-
});
|
|
101
|
-
return date.valueOf() / 1000;
|
|
102
|
-
}
|
|
103
|
-
static isValid(d) {
|
|
104
|
-
return this.parseOrNull(d) !== null;
|
|
105
|
-
}
|
|
106
|
-
static now() {
|
|
107
|
-
return new LocalTime(new Date());
|
|
108
|
-
}
|
|
109
|
-
static fromComponents(c) {
|
|
110
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day || 1, c.hour || 0, c.minute || 0, c.second || 0));
|
|
111
|
-
}
|
|
112
|
-
static fromDateUTC(d) {
|
|
113
|
-
return new LocalTime(new Date(d.toISOString()));
|
|
35
|
+
local() {
|
|
36
|
+
return new LocalTime(new Date(this.$date.getTime()));
|
|
114
37
|
}
|
|
115
38
|
get(unit) {
|
|
116
39
|
if (unit === 'year') {
|
|
@@ -213,7 +136,7 @@ export class LocalTime {
|
|
|
213
136
|
}
|
|
214
137
|
if (unit === 'year' || unit === 'month') {
|
|
215
138
|
const d = addMonths(this.$date, unit === 'month' ? num : num * 12, mutate);
|
|
216
|
-
return mutate ? this :
|
|
139
|
+
return mutate ? this : localTime.of(d);
|
|
217
140
|
}
|
|
218
141
|
return this.set(unit, this.get(unit) + num, mutate);
|
|
219
142
|
}
|
|
@@ -224,16 +147,16 @@ export class LocalTime {
|
|
|
224
147
|
return Math.abs(this.diff(other, unit));
|
|
225
148
|
}
|
|
226
149
|
diff(other, unit) {
|
|
227
|
-
const date2 =
|
|
150
|
+
const date2 = localTime.parseToDate(other);
|
|
228
151
|
const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000;
|
|
229
152
|
if (!secDiff)
|
|
230
153
|
return 0;
|
|
231
154
|
let r;
|
|
232
155
|
if (unit === 'year') {
|
|
233
|
-
r = differenceInMonths(this
|
|
156
|
+
r = differenceInMonths(this.$date, date2) / 12;
|
|
234
157
|
}
|
|
235
158
|
else if (unit === 'month') {
|
|
236
|
-
r = differenceInMonths(this
|
|
159
|
+
r = differenceInMonths(this.$date, date2);
|
|
237
160
|
}
|
|
238
161
|
else if (unit === 'day') {
|
|
239
162
|
r = secDiff / SECONDS_IN_DAY;
|
|
@@ -300,7 +223,7 @@ export class LocalTime {
|
|
|
300
223
|
}
|
|
301
224
|
else {
|
|
302
225
|
// year or month
|
|
303
|
-
const lastDay =
|
|
226
|
+
const lastDay = localDate.getMonthLength(d.getFullYear(), d.getMonth() + 1);
|
|
304
227
|
d.setDate(lastDay);
|
|
305
228
|
}
|
|
306
229
|
}
|
|
@@ -313,35 +236,7 @@ export class LocalTime {
|
|
|
313
236
|
* E.g 31 for January.
|
|
314
237
|
*/
|
|
315
238
|
daysInMonth() {
|
|
316
|
-
return
|
|
317
|
-
}
|
|
318
|
-
static sort(items, mutate = false, dir = 'asc') {
|
|
319
|
-
const mod = dir === 'desc' ? -1 : 1;
|
|
320
|
-
return (mutate ? items : [...items]).sort((a, b) => {
|
|
321
|
-
const v1 = a.$date.valueOf();
|
|
322
|
-
const v2 = b.$date.valueOf();
|
|
323
|
-
if (v1 === v2)
|
|
324
|
-
return 0;
|
|
325
|
-
return (v1 < v2 ? -1 : 1) * mod;
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
static earliestOrUndefined(items) {
|
|
329
|
-
return items.length ? LocalTime.earliest(items) : undefined;
|
|
330
|
-
}
|
|
331
|
-
static earliest(items) {
|
|
332
|
-
_assert(items.length, 'LocalTime.earliest called on empty array');
|
|
333
|
-
return items
|
|
334
|
-
.map(i => LocalTime.of(i))
|
|
335
|
-
.reduce((min, item) => (min.isSameOrBefore(item) ? min : item));
|
|
336
|
-
}
|
|
337
|
-
static latestOrUndefined(items) {
|
|
338
|
-
return items.length ? LocalTime.latest(items) : undefined;
|
|
339
|
-
}
|
|
340
|
-
static latest(items) {
|
|
341
|
-
_assert(items.length, 'LocalTime.latest called on empty array');
|
|
342
|
-
return items
|
|
343
|
-
.map(i => LocalTime.of(i))
|
|
344
|
-
.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
|
|
239
|
+
return localDate.getMonthLength(this.$date.getFullYear(), this.$date.getMonth() + 1);
|
|
345
240
|
}
|
|
346
241
|
isSame(d) {
|
|
347
242
|
return this.cmp(d) === 0;
|
|
@@ -380,13 +275,13 @@ export class LocalTime {
|
|
|
380
275
|
* Third argument allows to override "now".
|
|
381
276
|
*/
|
|
382
277
|
isOlderThan(n, unit, now) {
|
|
383
|
-
return this.isBefore(
|
|
278
|
+
return this.isBefore(localTime.of(now !== null && now !== void 0 ? now : new Date()).plus(-n, unit));
|
|
384
279
|
}
|
|
385
280
|
/**
|
|
386
281
|
* Checks if this localTime is same or older (<=) than "now" by X units.
|
|
387
282
|
*/
|
|
388
283
|
isSameOrOlderThan(n, unit, now) {
|
|
389
|
-
return this.isSameOrBefore(
|
|
284
|
+
return this.isSameOrBefore(localTime.of(now !== null && now !== void 0 ? now : new Date()).plus(-n, unit));
|
|
390
285
|
}
|
|
391
286
|
/**
|
|
392
287
|
* Checks if this localTime is younger (>) than "now" by X units.
|
|
@@ -398,13 +293,13 @@ export class LocalTime {
|
|
|
398
293
|
* Third argument allows to override "now".
|
|
399
294
|
*/
|
|
400
295
|
isYoungerThan(n, unit, now) {
|
|
401
|
-
return this.isAfter(
|
|
296
|
+
return this.isAfter(localTime.of(now !== null && now !== void 0 ? now : new Date()).plus(-n, unit));
|
|
402
297
|
}
|
|
403
298
|
/**
|
|
404
299
|
* Checks if this localTime is same or younger (>=) than "now" by X units.
|
|
405
300
|
*/
|
|
406
301
|
isSameOrYoungerThan(n, unit, now) {
|
|
407
|
-
return this.isSameOrAfter(
|
|
302
|
+
return this.isSameOrAfter(localTime.of(now !== null && now !== void 0 ? now : new Date()).plus(-n, unit));
|
|
408
303
|
}
|
|
409
304
|
/**
|
|
410
305
|
* Returns 1 if this > d
|
|
@@ -413,20 +308,13 @@ export class LocalTime {
|
|
|
413
308
|
*/
|
|
414
309
|
cmp(d) {
|
|
415
310
|
const t1 = this.$date.valueOf();
|
|
416
|
-
const t2 =
|
|
311
|
+
const t2 = localTime.parseToDate(d).valueOf();
|
|
417
312
|
if (t1 === t2)
|
|
418
313
|
return 0;
|
|
419
314
|
return t1 < t2 ? -1 : 1;
|
|
420
315
|
}
|
|
421
316
|
components() {
|
|
422
|
-
return {
|
|
423
|
-
year: this.$date.getFullYear(),
|
|
424
|
-
month: this.$date.getMonth() + 1,
|
|
425
|
-
day: this.$date.getDate(),
|
|
426
|
-
hour: this.$date.getHours(),
|
|
427
|
-
minute: this.$date.getMinutes(),
|
|
428
|
-
second: this.$date.getSeconds(),
|
|
429
|
-
};
|
|
317
|
+
return Object.assign(Object.assign({}, this.dateComponents()), this.timeComponents());
|
|
430
318
|
}
|
|
431
319
|
dateComponents() {
|
|
432
320
|
return {
|
|
@@ -443,7 +331,7 @@ export class LocalTime {
|
|
|
443
331
|
};
|
|
444
332
|
}
|
|
445
333
|
fromNow(now = new Date()) {
|
|
446
|
-
const msDiff =
|
|
334
|
+
const msDiff = localTime.parseToDate(now).valueOf() - this.$date.valueOf();
|
|
447
335
|
if (msDiff === 0)
|
|
448
336
|
return 'now';
|
|
449
337
|
if (msDiff >= 0) {
|
|
@@ -467,7 +355,7 @@ export class LocalTime {
|
|
|
467
355
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
468
356
|
}
|
|
469
357
|
toLocalDate() {
|
|
470
|
-
return
|
|
358
|
+
return localDate.fromDate(this.$date);
|
|
471
359
|
}
|
|
472
360
|
/**
|
|
473
361
|
* Returns e.g: `1984-06-21 17:56:21`
|
|
@@ -547,60 +435,131 @@ export class LocalTime {
|
|
|
547
435
|
return fmt(this);
|
|
548
436
|
}
|
|
549
437
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
}
|
|
562
|
-
/**
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
438
|
+
class LocalTimeFactory {
|
|
439
|
+
/**
|
|
440
|
+
* Parses input String into LocalDate.
|
|
441
|
+
* Input can already be a LocalDate - it is returned as-is in that case.
|
|
442
|
+
*/
|
|
443
|
+
of(d) {
|
|
444
|
+
const t = this.parseOrNull(d);
|
|
445
|
+
_assert(t !== null, `Cannot parse "${d}" into LocalTime`, {
|
|
446
|
+
input: d,
|
|
447
|
+
});
|
|
448
|
+
return t;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Create LocalTime from unixTimestamp in milliseconds (not in seconds).
|
|
452
|
+
*/
|
|
453
|
+
ofMillis(millis) {
|
|
454
|
+
return this.of(new Date(millis));
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Returns null if invalid
|
|
458
|
+
*/
|
|
459
|
+
parseOrNull(d) {
|
|
460
|
+
if (!d)
|
|
461
|
+
return null;
|
|
462
|
+
if (d instanceof LocalTime)
|
|
463
|
+
return d;
|
|
464
|
+
let date;
|
|
465
|
+
if (d instanceof Date) {
|
|
466
|
+
date = d;
|
|
467
|
+
}
|
|
468
|
+
else if (typeof d === 'number') {
|
|
469
|
+
date = new Date(d * 1000);
|
|
470
|
+
}
|
|
471
|
+
else if (typeof d !== 'string') {
|
|
472
|
+
// unexpected type, e.g Function or something
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
// Slicing removes the "timezone component", and makes the date "local"
|
|
477
|
+
// e.g 2022-04-06T23:15:00+09:00
|
|
478
|
+
// becomes 2022-04-06T23:15:00
|
|
479
|
+
date = new Date(d.slice(0, 19));
|
|
480
|
+
// We used to slice to remove the timezone information, now we don't
|
|
481
|
+
// date = new Date(d)
|
|
482
|
+
}
|
|
483
|
+
// validation
|
|
484
|
+
if (isNaN(date.getDate())) {
|
|
485
|
+
// throw new TypeError(`Cannot parse "${d}" into LocalTime`)
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
return new LocalTime(date);
|
|
489
|
+
}
|
|
490
|
+
parseToDate(d) {
|
|
491
|
+
if (d instanceof LocalTime)
|
|
492
|
+
return d.$date;
|
|
493
|
+
if (d instanceof Date)
|
|
494
|
+
return d;
|
|
495
|
+
const date = typeof d === 'number' ? new Date(d * 1000) : new Date(d);
|
|
496
|
+
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to Date`, {
|
|
497
|
+
input: d,
|
|
498
|
+
});
|
|
499
|
+
return date;
|
|
500
|
+
}
|
|
501
|
+
parseToUnixTimestamp(d) {
|
|
502
|
+
if (typeof d === 'number')
|
|
503
|
+
return d;
|
|
504
|
+
if (d instanceof LocalTime)
|
|
505
|
+
return d.unix();
|
|
506
|
+
const date = d instanceof Date ? d : new Date(d);
|
|
507
|
+
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to UnixTimestamp`, {
|
|
508
|
+
input: d,
|
|
509
|
+
});
|
|
510
|
+
return date.valueOf() / 1000;
|
|
511
|
+
}
|
|
512
|
+
isValid(d) {
|
|
513
|
+
return this.parseOrNull(d) !== null;
|
|
514
|
+
}
|
|
515
|
+
now() {
|
|
516
|
+
return new LocalTime(new Date());
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Creates a LocalTime from the input, unless it's falsy - then returns undefined.
|
|
520
|
+
*
|
|
521
|
+
* `localTime` function will instead return LocalTime of `now` for falsy input.
|
|
522
|
+
*/
|
|
523
|
+
orUndefined(d) {
|
|
524
|
+
return d ? this.of(d) : undefined;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Creates a LocalTime from the input, unless it's falsy - then returns LocalTime.now
|
|
528
|
+
*/
|
|
529
|
+
orNow(d) {
|
|
530
|
+
return d ? this.of(d) : this.now();
|
|
531
|
+
}
|
|
532
|
+
fromComponents(c) {
|
|
533
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day || 1, c.hour || 0, c.minute || 0, c.second || 0));
|
|
534
|
+
}
|
|
535
|
+
sort(items, dir = 'asc', mutate = false) {
|
|
536
|
+
const mod = dir === 'desc' ? -1 : 1;
|
|
537
|
+
return (mutate ? items : [...items]).sort((a, b) => {
|
|
538
|
+
const v1 = a.$date.valueOf();
|
|
539
|
+
const v2 = b.$date.valueOf();
|
|
540
|
+
if (v1 === v2)
|
|
541
|
+
return 0;
|
|
542
|
+
return (v1 < v2 ? -1 : 1) * mod;
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
minOrUndefined(items) {
|
|
546
|
+
return items.length ? this.min(items) : undefined;
|
|
547
|
+
}
|
|
548
|
+
min(items) {
|
|
549
|
+
_assert(items.length, 'localTime.min called on empty array');
|
|
550
|
+
return items
|
|
551
|
+
.map(i => this.of(i))
|
|
552
|
+
.reduce((min, item) => (min.$date.valueOf() <= item.$date.valueOf() ? min : item));
|
|
553
|
+
}
|
|
554
|
+
maxOrUndefined(items) {
|
|
555
|
+
return items.length ? this.max(items) : undefined;
|
|
556
|
+
}
|
|
557
|
+
max(items) {
|
|
558
|
+
_assert(items.length, 'localTime.max called on empty array');
|
|
559
|
+
return items
|
|
560
|
+
.map(i => this.of(i))
|
|
561
|
+
.reduce((max, item) => (max.$date.valueOf() >= item.$date.valueOf() ? max : item));
|
|
562
|
+
}
|
|
604
563
|
}
|
|
605
564
|
// based on: https://github.com/date-fns/date-fns/blob/master/src/getISOWeek/index.ts
|
|
606
565
|
function getWeek(date) {
|
|
@@ -675,7 +634,7 @@ function addMonths(d, num, mutate = false) {
|
|
|
675
634
|
year--;
|
|
676
635
|
month += 12;
|
|
677
636
|
}
|
|
678
|
-
const monthLen =
|
|
637
|
+
const monthLen = localDate.getMonthLength(year, month);
|
|
679
638
|
if (day > monthLen)
|
|
680
639
|
day = monthLen;
|
|
681
640
|
d.setFullYear(year, month - 1, day);
|
|
@@ -690,3 +649,37 @@ function differenceInMonths(a, b) {
|
|
|
690
649
|
const anchor2 = addMonths(a, wholeMonthDiff + sign).getTime();
|
|
691
650
|
return -(wholeMonthDiff + ((b.getTime() - anchor) / (anchor2 - anchor)) * sign);
|
|
692
651
|
}
|
|
652
|
+
const localTimeFactory = new LocalTimeFactory();
|
|
653
|
+
export const localTime = localTimeFactory.of.bind(localTimeFactory);
|
|
654
|
+
// The line below is the blackest of black magic I have ever written in 2024.
|
|
655
|
+
// And probably 2023 as well.
|
|
656
|
+
Object.setPrototypeOf(localTime, localTimeFactory);
|
|
657
|
+
/**
|
|
658
|
+
Convenience function to return current Unix timestamp in seconds.
|
|
659
|
+
Like Date.now(), but in seconds.
|
|
660
|
+
*/
|
|
661
|
+
export function nowUnix() {
|
|
662
|
+
return Math.floor(Date.now() / 1000);
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
666
|
+
* to the local time to get UTC time.
|
|
667
|
+
*
|
|
668
|
+
* E.g utcOffset for CEST is -120,
|
|
669
|
+
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
670
|
+
*
|
|
671
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
672
|
+
*/
|
|
673
|
+
export function getUTCOffsetMinutes() {
|
|
674
|
+
return -new Date().getTimezoneOffset() || 0;
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
678
|
+
*
|
|
679
|
+
* E.g for CEST it is -2.
|
|
680
|
+
*
|
|
681
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
682
|
+
*/
|
|
683
|
+
export function getUTCOffsetHours() {
|
|
684
|
+
return Math.round(getUTCOffsetMinutes() / 60);
|
|
685
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { localTime } from './localTime';
|
|
2
2
|
/**
|
|
3
3
|
* Class that supports an "interval of time" between 2 timestamps - start and end.
|
|
4
4
|
* Example: `1649267185/1649267187`.
|
|
@@ -11,7 +11,7 @@ export class TimeInterval {
|
|
|
11
11
|
this.$end = $end;
|
|
12
12
|
}
|
|
13
13
|
static of(start, end) {
|
|
14
|
-
return new TimeInterval(
|
|
14
|
+
return new TimeInterval(localTime.parseToUnixTimestamp(start), localTime.parseToUnixTimestamp(end));
|
|
15
15
|
}
|
|
16
16
|
get start() {
|
|
17
17
|
return this.$start;
|
|
@@ -20,10 +20,10 @@ export class TimeInterval {
|
|
|
20
20
|
return this.$end;
|
|
21
21
|
}
|
|
22
22
|
get startTime() {
|
|
23
|
-
return
|
|
23
|
+
return localTime(this.$start);
|
|
24
24
|
}
|
|
25
25
|
get endTime() {
|
|
26
|
-
return
|
|
26
|
+
return localTime(this.$end);
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* Parses string like `1649267185/1649267187` into a TimeInterval.
|
|
@@ -55,7 +55,7 @@ export class TimeInterval {
|
|
|
55
55
|
return this.cmp(d) >= 0;
|
|
56
56
|
}
|
|
57
57
|
includes(d, incl = '[)') {
|
|
58
|
-
d =
|
|
58
|
+
d = localTime.parseToUnixTimestamp(d);
|
|
59
59
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
60
60
|
if (d < this.$start || (d === this.$start && incl[0] === '('))
|
|
61
61
|
return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { localTime } from '../datetime/localTime';
|
|
2
2
|
export function generateBuildInfoDev() {
|
|
3
|
-
const now =
|
|
3
|
+
const now = localTime.now();
|
|
4
4
|
const ts = now.unix();
|
|
5
5
|
const rev = 'devRev';
|
|
6
6
|
const branchName = 'devBranch';
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/js-lib",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.233.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky",
|
|
6
6
|
"build-prod": "build-prod-esm-cjs",
|
|
7
|
-
"test-tz1": "TZ=Europe/Stockholm test local",
|
|
8
|
-
"test-tz2": "TZ=JST-9 test local",
|
|
7
|
+
"test-tz1": "TZ=Europe/Stockholm yarn test local",
|
|
8
|
+
"test-tz2": "TZ=JST-9 yarn test local",
|
|
9
9
|
"docs-dev": "vitepress dev docs --open",
|
|
10
10
|
"docs-build": "vitepress build docs",
|
|
11
11
|
"docs-preview": "vitepress preview docs"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"zod": "^3.20.2"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@naturalcycles/bench-lib": "^
|
|
18
|
+
"@naturalcycles/bench-lib": "^3.0.0",
|
|
19
19
|
"@naturalcycles/dev-lib": "^13.0.1",
|
|
20
20
|
"@naturalcycles/nodejs-lib": "^13.0.1",
|
|
21
21
|
"@naturalcycles/time-lib": "^3.5.1",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Inclusiveness } from '../types'
|
|
2
|
-
import
|
|
3
|
-
import { LocalDate, localDateRange } from './localDate'
|
|
2
|
+
import { localDate, LocalDateInput, LocalDateUnit, LocalDate } from './localDate'
|
|
4
3
|
|
|
5
4
|
export type DateIntervalConfig = DateInterval | DateIntervalString
|
|
6
5
|
export type DateIntervalString = string
|
|
@@ -17,7 +16,7 @@ export class DateInterval {
|
|
|
17
16
|
) {}
|
|
18
17
|
|
|
19
18
|
static of(start: LocalDateInput, end: LocalDateInput): DateInterval {
|
|
20
|
-
return new DateInterval(
|
|
19
|
+
return new DateInterval(localDate(start), localDate(end))
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
/**
|
|
@@ -32,7 +31,7 @@ export class DateInterval {
|
|
|
32
31
|
throw new Error(`Cannot parse "${d}" into DateInterval`)
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
return new DateInterval(
|
|
34
|
+
return new DateInterval(localDate(start), localDate(end))
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
isSame(d: DateIntervalConfig): boolean {
|
|
@@ -61,7 +60,7 @@ export class DateInterval {
|
|
|
61
60
|
* Ranges of DateInterval (start, end) are INCLUSIVE.
|
|
62
61
|
*/
|
|
63
62
|
includes(d: LocalDateInput, incl: Inclusiveness = '[]'): boolean {
|
|
64
|
-
d =
|
|
63
|
+
d = localDate(d)
|
|
65
64
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
66
65
|
return d.isAfter(this.start, incl[0] === '[') && d.isBefore(this.end, incl[1] === ']')
|
|
67
66
|
}
|
|
@@ -82,14 +81,14 @@ export class DateInterval {
|
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
getDays(incl: Inclusiveness = '[]'): LocalDate[] {
|
|
85
|
-
return
|
|
84
|
+
return localDate.range(this.start, this.end, incl, 1, 'day')
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
/**
|
|
89
88
|
* Returns an array of LocalDates that are included in the interval.
|
|
90
89
|
*/
|
|
91
90
|
range(incl: Inclusiveness = '[]', step = 1, stepUnit: LocalDateUnit = 'day'): LocalDate[] {
|
|
92
|
-
return
|
|
91
|
+
return localDate.range(this.start, this.end, incl, step, stepUnit)
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
toString(): DateIntervalString {
|