@naturalcycles/js-lib 14.243.0 → 14.244.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.js +1 -1
- package/dist/datetime/localDate.d.ts +31 -26
- package/dist/datetime/localDate.js +180 -154
- package/dist/datetime/localTime.d.ts +43 -41
- package/dist/datetime/localTime.js +178 -118
- package/dist/datetime/timeInterval.js +2 -2
- package/dist/env/buildInfo.js +2 -2
- package/dist-esm/datetime/dateInterval.js +1 -1
- package/dist-esm/datetime/localDate.js +180 -154
- package/dist-esm/datetime/localTime.js +178 -118
- package/dist-esm/datetime/timeInterval.js +2 -2
- package/dist-esm/env/buildInfo.js +2 -2
- package/package.json +2 -1
- package/src/datetime/dateInterval.ts +1 -1
- package/src/datetime/localDate.ts +188 -168
- package/src/datetime/localTime.ts +191 -149
- package/src/datetime/timeInterval.ts +2 -5
- package/src/env/buildInfo.ts +2 -2
|
@@ -32,6 +32,7 @@ export type LocalTimeInputNullable = LocalTimeInput | null | undefined
|
|
|
32
32
|
export type LocalTimeFormatter = (ld: LocalTime) => string
|
|
33
33
|
|
|
34
34
|
export type DateTimeObject = DateObject & TimeObject
|
|
35
|
+
export type DateTimeObjectInput = DateObject & Partial<TimeObject>
|
|
35
36
|
|
|
36
37
|
export interface DateObject {
|
|
37
38
|
year: number
|
|
@@ -51,6 +52,10 @@ const SECONDS_IN_DAY = 86400
|
|
|
51
52
|
// const MILLISECONDS_IN_DAY = 86400000
|
|
52
53
|
// const MILLISECONDS_IN_MINUTE = 60000
|
|
53
54
|
const VALID_DAYS_OF_WEEK = new Set([1, 2, 3, 4, 5, 6, 7])
|
|
55
|
+
// It supports 2 forms:
|
|
56
|
+
// 1. 2023-03-03
|
|
57
|
+
// 2. 2023-03-03T05:10:02
|
|
58
|
+
const DATE_TIME_REGEX = /^(\d{4})-(\d{2})-(\d{2})([T\s](\d{2}):(\d{2}):(\d{2}))?/
|
|
54
59
|
|
|
55
60
|
export class LocalTime {
|
|
56
61
|
constructor(public $date: Date) {}
|
|
@@ -59,7 +64,7 @@ export class LocalTime {
|
|
|
59
64
|
* Returns [cloned] LocalTime that is based on the same unixtimestamp, but in UTC timezone.
|
|
60
65
|
* Opposite of `.local()` method.
|
|
61
66
|
*/
|
|
62
|
-
|
|
67
|
+
toUTC(): LocalTime {
|
|
63
68
|
return new LocalTime(new Date(this.$date.toISOString()))
|
|
64
69
|
}
|
|
65
70
|
|
|
@@ -67,7 +72,7 @@ export class LocalTime {
|
|
|
67
72
|
* Returns [cloned] LocalTime that is based on the same unixtimestamp, but in local timezone.
|
|
68
73
|
* Opposite of `.utc()` method.
|
|
69
74
|
*/
|
|
70
|
-
|
|
75
|
+
toLocal(): LocalTime {
|
|
71
76
|
return new LocalTime(new Date(this.$date.getTime()))
|
|
72
77
|
}
|
|
73
78
|
|
|
@@ -193,58 +198,60 @@ export class LocalTime {
|
|
|
193
198
|
return t
|
|
194
199
|
}
|
|
195
200
|
|
|
196
|
-
year(): number
|
|
197
|
-
|
|
198
|
-
year(v?: number): number | LocalTime {
|
|
199
|
-
return v === undefined ? this.get('year') : this.set('year', v)
|
|
201
|
+
get year(): number {
|
|
202
|
+
return this.$date.getFullYear()
|
|
200
203
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
month(v?: number): number | LocalTime {
|
|
204
|
-
return v === undefined ? this.get('month') : this.set('month', v)
|
|
204
|
+
setYear(v: number): LocalTime {
|
|
205
|
+
return this.set('year', v)
|
|
205
206
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
week(v?: number): number | LocalTime {
|
|
209
|
-
return v === undefined ? getWeek(this.$date) : this.set('week', v)
|
|
207
|
+
get month(): number {
|
|
208
|
+
return this.$date.getMonth() + 1
|
|
210
209
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
210
|
+
setMonth(v: number): LocalTime {
|
|
211
|
+
return this.set('month', v)
|
|
212
|
+
}
|
|
213
|
+
get week(): number {
|
|
214
|
+
return getWeek(this.$date)
|
|
215
|
+
}
|
|
216
|
+
setWeek(v: number): LocalTime {
|
|
217
|
+
return this.set('week', v)
|
|
218
|
+
}
|
|
219
|
+
get day(): number {
|
|
220
|
+
return this.$date.getDate()
|
|
221
|
+
}
|
|
222
|
+
setDay(v: number): LocalTime {
|
|
223
|
+
return this.set('day', v)
|
|
224
|
+
}
|
|
225
|
+
get hour(): number {
|
|
226
|
+
return this.$date.getHours()
|
|
227
|
+
}
|
|
228
|
+
setHour(v: number): LocalTime {
|
|
229
|
+
return this.set('hour', v)
|
|
230
|
+
}
|
|
231
|
+
get minute(): number {
|
|
232
|
+
return this.$date.getMinutes()
|
|
233
|
+
}
|
|
234
|
+
setMinute(v: number): LocalTime {
|
|
235
|
+
return this.set('minute', v)
|
|
236
|
+
}
|
|
237
|
+
get second(): number {
|
|
238
|
+
return this.$date.getSeconds()
|
|
239
|
+
}
|
|
240
|
+
setSecond(v: number): LocalTime {
|
|
241
|
+
return this.set('second', v)
|
|
215
242
|
}
|
|
216
243
|
|
|
217
244
|
/**
|
|
218
245
|
* Based on ISO: 1-7 is Mon-Sun.
|
|
219
246
|
*/
|
|
220
|
-
dayOfWeek(): ISODayOfWeek
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (v === undefined) {
|
|
226
|
-
return dow
|
|
227
|
-
}
|
|
228
|
-
|
|
247
|
+
get dayOfWeek(): ISODayOfWeek {
|
|
248
|
+
return (this.$date.getDay() || 7) as ISODayOfWeek
|
|
249
|
+
}
|
|
250
|
+
setDayOfWeek(v: ISODayOfWeek): LocalTime {
|
|
229
251
|
_assert(VALID_DAYS_OF_WEEK.has(v), `Invalid dayOfWeek: ${v}`)
|
|
230
|
-
|
|
252
|
+
const dow = this.$date.getDay() || 7
|
|
231
253
|
return this.plus(v - dow, 'day')
|
|
232
254
|
}
|
|
233
|
-
hour(): number
|
|
234
|
-
hour(v: number): LocalTime
|
|
235
|
-
hour(v?: number): number | LocalTime {
|
|
236
|
-
return v === undefined ? this.get('hour') : this.set('hour', v)
|
|
237
|
-
}
|
|
238
|
-
minute(): number
|
|
239
|
-
minute(v: number): LocalTime
|
|
240
|
-
minute(v?: number): number | LocalTime {
|
|
241
|
-
return v === undefined ? this.get('minute') : this.set('minute', v)
|
|
242
|
-
}
|
|
243
|
-
second(): number
|
|
244
|
-
second(v: number): LocalTime
|
|
245
|
-
second(v?: number): number | LocalTime {
|
|
246
|
-
return v === undefined ? this.get('second') : this.set('second', v)
|
|
247
|
-
}
|
|
248
255
|
|
|
249
256
|
setComponents(c: Partial<DateTimeObject>, mutate = false): LocalTime {
|
|
250
257
|
const d = mutate ? this.$date : new Date(this.$date)
|
|
@@ -322,7 +329,7 @@ export class LocalTime {
|
|
|
322
329
|
|
|
323
330
|
if (unit === 'year' || unit === 'month') {
|
|
324
331
|
const d = addMonths(this.$date, unit === 'month' ? num : num * 12, mutate)
|
|
325
|
-
return mutate ? this : localTime.
|
|
332
|
+
return mutate ? this : localTime.from(d)
|
|
326
333
|
}
|
|
327
334
|
|
|
328
335
|
return this.set(unit, this.get(unit) + num, mutate)
|
|
@@ -337,7 +344,7 @@ export class LocalTime {
|
|
|
337
344
|
}
|
|
338
345
|
|
|
339
346
|
diff(other: LocalTimeInput, unit: LocalTimeUnit): number {
|
|
340
|
-
const date2 = localTime.
|
|
347
|
+
const date2 = localTime.from(other).$date
|
|
341
348
|
|
|
342
349
|
const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000
|
|
343
350
|
if (!secDiff) return 0
|
|
@@ -427,37 +434,32 @@ export class LocalTime {
|
|
|
427
434
|
* Returns how many days are in the current month.
|
|
428
435
|
* E.g 31 for January.
|
|
429
436
|
*/
|
|
430
|
-
daysInMonth(): number {
|
|
437
|
+
get daysInMonth(): number {
|
|
431
438
|
return localDate.getMonthLength(this.$date.getFullYear(), this.$date.getMonth() + 1)
|
|
432
439
|
}
|
|
433
440
|
|
|
434
441
|
isSame(d: LocalTimeInput): boolean {
|
|
435
|
-
return this.
|
|
442
|
+
return this.compare(d) === 0
|
|
436
443
|
}
|
|
437
|
-
|
|
438
444
|
isBefore(d: LocalTimeInput, inclusive = false): boolean {
|
|
439
|
-
const r = this.
|
|
445
|
+
const r = this.compare(d)
|
|
440
446
|
return r === -1 || (r === 0 && inclusive)
|
|
441
447
|
}
|
|
442
|
-
|
|
443
448
|
isSameOrBefore(d: LocalTimeInput): boolean {
|
|
444
|
-
return this.
|
|
449
|
+
return this.compare(d) <= 0
|
|
445
450
|
}
|
|
446
|
-
|
|
447
451
|
isAfter(d: LocalTimeInput, inclusive = false): boolean {
|
|
448
|
-
const r = this.
|
|
452
|
+
const r = this.compare(d)
|
|
449
453
|
return r === 1 || (r === 0 && inclusive)
|
|
450
454
|
}
|
|
451
|
-
|
|
452
455
|
isSameOrAfter(d: LocalTimeInput): boolean {
|
|
453
|
-
return this.
|
|
456
|
+
return this.compare(d) >= 0
|
|
454
457
|
}
|
|
455
|
-
|
|
456
458
|
isBetween(min: LocalTimeInput, max: LocalTimeInput, incl: Inclusiveness = '[)'): boolean {
|
|
457
|
-
let r = this.
|
|
459
|
+
let r = this.compare(min)
|
|
458
460
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
459
461
|
if (r < 0 || (r === 0 && incl[0] === '(')) return false
|
|
460
|
-
r = this.
|
|
462
|
+
r = this.compare(max)
|
|
461
463
|
if (r > 0 || (r === 0 && incl[1] === ')')) return false
|
|
462
464
|
return true
|
|
463
465
|
}
|
|
@@ -472,14 +474,14 @@ export class LocalTime {
|
|
|
472
474
|
* Third argument allows to override "now".
|
|
473
475
|
*/
|
|
474
476
|
isOlderThan(n: number, unit: LocalTimeUnit, now?: LocalTimeInput): boolean {
|
|
475
|
-
return this.isBefore(localTime.
|
|
477
|
+
return this.isBefore(localTime.from(now ?? new Date()).plus(-n, unit))
|
|
476
478
|
}
|
|
477
479
|
|
|
478
480
|
/**
|
|
479
481
|
* Checks if this localTime is same or older (<=) than "now" by X units.
|
|
480
482
|
*/
|
|
481
483
|
isSameOrOlderThan(n: number, unit: LocalTimeUnit, now?: LocalTimeInput): boolean {
|
|
482
|
-
return this.isSameOrBefore(localTime.
|
|
484
|
+
return this.isSameOrBefore(localTime.from(now ?? new Date()).plus(-n, unit))
|
|
483
485
|
}
|
|
484
486
|
|
|
485
487
|
/**
|
|
@@ -492,14 +494,14 @@ export class LocalTime {
|
|
|
492
494
|
* Third argument allows to override "now".
|
|
493
495
|
*/
|
|
494
496
|
isYoungerThan(n: number, unit: LocalTimeUnit, now?: LocalTimeInput): boolean {
|
|
495
|
-
return this.isAfter(localTime.
|
|
497
|
+
return this.isAfter(localTime.from(now ?? new Date()).plus(-n, unit))
|
|
496
498
|
}
|
|
497
499
|
|
|
498
500
|
/**
|
|
499
501
|
* Checks if this localTime is same or younger (>=) than "now" by X units.
|
|
500
502
|
*/
|
|
501
503
|
isSameOrYoungerThan(n: number, unit: LocalTimeUnit, now?: LocalTimeInput): boolean {
|
|
502
|
-
return this.isSameOrAfter(localTime.
|
|
504
|
+
return this.isSameOrAfter(localTime.from(now ?? new Date()).plus(-n, unit))
|
|
503
505
|
}
|
|
504
506
|
|
|
505
507
|
getAgeInYears(now?: LocalTimeInput): number {
|
|
@@ -521,7 +523,7 @@ export class LocalTime {
|
|
|
521
523
|
return this.getAgeIn('second', now)
|
|
522
524
|
}
|
|
523
525
|
getAgeIn(unit: LocalTimeUnit, now?: LocalTimeInput): number {
|
|
524
|
-
return localTime.
|
|
526
|
+
return localTime.from(now ?? new Date()).diff(this, unit)
|
|
525
527
|
}
|
|
526
528
|
|
|
527
529
|
/**
|
|
@@ -529,21 +531,21 @@ export class LocalTime {
|
|
|
529
531
|
* returns 0 if they are equal
|
|
530
532
|
* returns -1 if this < d
|
|
531
533
|
*/
|
|
532
|
-
|
|
534
|
+
compare(d: LocalTimeInput): -1 | 0 | 1 {
|
|
533
535
|
const t1 = this.$date.valueOf()
|
|
534
|
-
const t2 = localTime.
|
|
536
|
+
const t2 = localTime.from(d).$date.valueOf()
|
|
535
537
|
if (t1 === t2) return 0
|
|
536
538
|
return t1 < t2 ? -1 : 1
|
|
537
539
|
}
|
|
538
540
|
|
|
539
|
-
|
|
541
|
+
toDateTimeObject(): DateTimeObject {
|
|
540
542
|
return {
|
|
541
|
-
...this.
|
|
542
|
-
...this.
|
|
543
|
+
...this.toDateObject(),
|
|
544
|
+
...this.toTimeObject(),
|
|
543
545
|
}
|
|
544
546
|
}
|
|
545
547
|
|
|
546
|
-
|
|
548
|
+
toDateObject(): DateObject {
|
|
547
549
|
return {
|
|
548
550
|
year: this.$date.getFullYear(),
|
|
549
551
|
month: this.$date.getMonth() + 1,
|
|
@@ -551,7 +553,7 @@ export class LocalTime {
|
|
|
551
553
|
}
|
|
552
554
|
}
|
|
553
555
|
|
|
554
|
-
|
|
556
|
+
toTimeObject(): TimeObject {
|
|
555
557
|
return {
|
|
556
558
|
hour: this.$date.getHours(),
|
|
557
559
|
minute: this.$date.getMinutes(),
|
|
@@ -559,8 +561,8 @@ export class LocalTime {
|
|
|
559
561
|
}
|
|
560
562
|
}
|
|
561
563
|
|
|
562
|
-
|
|
563
|
-
const msDiff = localTime.
|
|
564
|
+
toFromNowString(now: LocalTimeInput = new Date()): string {
|
|
565
|
+
const msDiff = localTime.from(now).$date.valueOf() - this.$date.valueOf()
|
|
564
566
|
|
|
565
567
|
if (msDiff === 0) return 'now'
|
|
566
568
|
|
|
@@ -571,7 +573,7 @@ export class LocalTime {
|
|
|
571
573
|
return `in ${_ms(msDiff * -1)}`
|
|
572
574
|
}
|
|
573
575
|
|
|
574
|
-
|
|
576
|
+
toDate(): Date {
|
|
575
577
|
return this.$date
|
|
576
578
|
}
|
|
577
579
|
|
|
@@ -579,11 +581,11 @@ export class LocalTime {
|
|
|
579
581
|
return new LocalTime(new Date(this.$date))
|
|
580
582
|
}
|
|
581
583
|
|
|
582
|
-
unix(): UnixTimestampNumber {
|
|
584
|
+
get unix(): UnixTimestampNumber {
|
|
583
585
|
return Math.floor(this.$date.valueOf() / 1000)
|
|
584
586
|
}
|
|
585
587
|
|
|
586
|
-
unixMillis(): UnixTimestampMillisNumber {
|
|
588
|
+
get unixMillis(): UnixTimestampMillisNumber {
|
|
587
589
|
return this.$date.valueOf()
|
|
588
590
|
}
|
|
589
591
|
|
|
@@ -620,7 +622,7 @@ export class LocalTime {
|
|
|
620
622
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
621
623
|
*/
|
|
622
624
|
toISODate(): IsoDateString {
|
|
623
|
-
const { year, month, day } = this.
|
|
625
|
+
const { year, month, day } = this.toDateObject()
|
|
624
626
|
|
|
625
627
|
return [
|
|
626
628
|
String(year).padStart(4, '0'),
|
|
@@ -636,7 +638,7 @@ export class LocalTime {
|
|
|
636
638
|
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
637
639
|
*/
|
|
638
640
|
toISOTime(seconds = true): string {
|
|
639
|
-
const { hour, minute, second } = this.
|
|
641
|
+
const { hour, minute, second } = this.toTimeObject()
|
|
640
642
|
|
|
641
643
|
return [
|
|
642
644
|
String(hour).padStart(2, '0'),
|
|
@@ -654,7 +656,7 @@ export class LocalTime {
|
|
|
654
656
|
* Returns e.g: `19840621_1705`
|
|
655
657
|
*/
|
|
656
658
|
toStringCompact(seconds = false): string {
|
|
657
|
-
const { year, month, day, hour, minute, second } = this.
|
|
659
|
+
const { year, month, day, hour, minute, second } = this.toDateTimeObject()
|
|
658
660
|
|
|
659
661
|
return [
|
|
660
662
|
String(year).padStart(4, '0'),
|
|
@@ -672,7 +674,7 @@ export class LocalTime {
|
|
|
672
674
|
}
|
|
673
675
|
|
|
674
676
|
toJSON(): UnixTimestampNumber {
|
|
675
|
-
return this.unix
|
|
677
|
+
return this.unix
|
|
676
678
|
}
|
|
677
679
|
|
|
678
680
|
toMonthId(): MonthId {
|
|
@@ -690,90 +692,136 @@ export class LocalTime {
|
|
|
690
692
|
|
|
691
693
|
class LocalTimeFactory {
|
|
692
694
|
/**
|
|
693
|
-
* Parses input String into
|
|
694
|
-
* Input can already be a
|
|
695
|
+
* Parses input String into LocalTime.
|
|
696
|
+
* Input can already be a LocalTime - it is returned as-is in that case.
|
|
695
697
|
*/
|
|
696
|
-
|
|
697
|
-
const
|
|
698
|
+
from(input: LocalTimeInput): LocalTime {
|
|
699
|
+
const lt = this.fromOrNull(input)
|
|
700
|
+
this.assertNotNull(lt, input)
|
|
701
|
+
return lt
|
|
702
|
+
}
|
|
698
703
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
704
|
+
fromDate(date: Date): LocalTime {
|
|
705
|
+
return new LocalTime(date)
|
|
706
|
+
}
|
|
702
707
|
|
|
703
|
-
|
|
708
|
+
fromUnix(ts: UnixTimestampNumber): LocalTime {
|
|
709
|
+
return new LocalTime(new Date(ts * 1000))
|
|
704
710
|
}
|
|
705
711
|
|
|
706
712
|
/**
|
|
707
713
|
* Create LocalTime from unixTimestamp in milliseconds (not in seconds).
|
|
708
714
|
*/
|
|
709
|
-
|
|
710
|
-
return
|
|
715
|
+
fromMillis(millis: UnixTimestampMillisNumber): LocalTime {
|
|
716
|
+
return new LocalTime(new Date(millis))
|
|
711
717
|
}
|
|
712
718
|
|
|
713
719
|
/**
|
|
714
720
|
* Returns null if invalid
|
|
715
721
|
*/
|
|
716
|
-
|
|
722
|
+
fromOrNull(d: LocalTimeInputNullable): LocalTime | null {
|
|
717
723
|
if (d instanceof LocalTime) return d
|
|
718
|
-
|
|
719
|
-
let date
|
|
720
|
-
|
|
721
724
|
if (d instanceof Date) {
|
|
722
|
-
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
725
|
+
return new LocalTime(d)
|
|
726
|
+
}
|
|
727
|
+
if (typeof d === 'number') {
|
|
728
|
+
return new LocalTime(new Date(d * 1000))
|
|
729
|
+
}
|
|
730
|
+
if (typeof d === 'string') {
|
|
731
|
+
return this.fromStringOrNull(d)
|
|
732
|
+
}
|
|
733
|
+
// This check is after checking the number, to support `0`
|
|
734
|
+
// unexpected type, e.g Function or something
|
|
735
|
+
return null
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
fromStringOrNull(s: string | undefined | null): LocalTime | null {
|
|
739
|
+
const date = this.parseStringToDateOrNull(s)
|
|
740
|
+
return date ? new LocalTime(date) : null
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
fromDateTimeObject(input: DateTimeObjectInput): LocalTime {
|
|
744
|
+
const { year, month, day = 1, hour = 0, minute = 0, second = 0 } = input
|
|
745
|
+
return new LocalTime(new Date(year, month - 1, day, hour, minute, second))
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
private parseStringToDateOrNull(s: string | undefined | null): Date | null {
|
|
749
|
+
if (!s) return null
|
|
750
|
+
// Slicing removes the "timezone component", and makes the date "local"
|
|
751
|
+
// e.g 2022-04-06T23:15:00+09:00
|
|
752
|
+
// becomes 2022-04-06T23:15:00
|
|
753
|
+
// date = new Date(d.slice(0, 19))
|
|
754
|
+
|
|
755
|
+
// Parsing is inspired by how Day.js does it
|
|
756
|
+
// Specifically, it ensures that `localTime('2023-03-03')` returns the expected Date, and not a day before
|
|
757
|
+
// Because `new Date('2023-03-03')` in NewYork gives you '2023-03-02 19:00:00 GMT-0500'
|
|
758
|
+
|
|
759
|
+
const m = s.match(DATE_TIME_REGEX)
|
|
760
|
+
// Validate in 3 ways:
|
|
761
|
+
// 1. Should match Regex.
|
|
762
|
+
// In some ways it's stricter than Date constructor, e.g it doesn't allow 2023/05/05
|
|
763
|
+
// In other ways it's looser, e.g it allows `2023-05-05T`, while Date constructor doesn't.
|
|
764
|
+
// 2. Date constructor (of Node/v8 implementation, which we know is different from e.g WebKit/Safari)
|
|
765
|
+
// should not return `Invalid Date`.
|
|
766
|
+
// 3. Year, month and day should be valid, e.g 2023-01-32 should not be allowed.
|
|
767
|
+
// UPD: Actually, 3 can be skipped, because 2 is catching it already
|
|
768
|
+
// UPD: 2 is skipped, 1 and 3 are kept
|
|
769
|
+
// if (!m || isNaN(new Date(s).getDate())) return null
|
|
770
|
+
if (!m) return null
|
|
771
|
+
const year = Number(m[1])
|
|
772
|
+
const month = Number(m[2])
|
|
773
|
+
const day = Number(m[3])
|
|
774
|
+
const hour = Number(m[5])
|
|
775
|
+
const minute = Number(m[6])
|
|
776
|
+
const second = Number(m[7])
|
|
777
|
+
|
|
778
|
+
// Validation for just the Date part
|
|
779
|
+
if (
|
|
780
|
+
!year ||
|
|
781
|
+
!month ||
|
|
782
|
+
month < 1 ||
|
|
783
|
+
month > 12 ||
|
|
784
|
+
!day ||
|
|
785
|
+
day < 1 ||
|
|
786
|
+
day > localDate.getMonthLength(year, month)
|
|
787
|
+
) {
|
|
730
788
|
return null
|
|
731
|
-
} else {
|
|
732
|
-
// Slicing removes the "timezone component", and makes the date "local"
|
|
733
|
-
// e.g 2022-04-06T23:15:00+09:00
|
|
734
|
-
// becomes 2022-04-06T23:15:00
|
|
735
|
-
date = new Date(d.slice(0, 19))
|
|
736
|
-
// We used to slice to remove the timezone information, now we don't
|
|
737
|
-
// date = new Date(d)
|
|
738
789
|
}
|
|
739
790
|
|
|
740
|
-
//
|
|
741
|
-
if (
|
|
742
|
-
|
|
791
|
+
// Validation for Date+Time string, since the string is longer than YYYY-MM-DD
|
|
792
|
+
if (
|
|
793
|
+
s.length > 10 &&
|
|
794
|
+
(isNaN(hour) ||
|
|
795
|
+
isNaN(minute) ||
|
|
796
|
+
isNaN(second) ||
|
|
797
|
+
hour < 0 ||
|
|
798
|
+
hour > 23 ||
|
|
799
|
+
minute < 0 ||
|
|
800
|
+
minute > 59 ||
|
|
801
|
+
second < 0 ||
|
|
802
|
+
second > 59)
|
|
803
|
+
) {
|
|
743
804
|
return null
|
|
744
805
|
}
|
|
745
806
|
|
|
746
|
-
return new
|
|
807
|
+
return new Date(year, month - 1, day, hour || 0, minute || 0, second || 0, 0)
|
|
747
808
|
}
|
|
748
809
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
if (d instanceof Date) return d
|
|
752
|
-
|
|
753
|
-
const date = typeof d === 'number' ? new Date(d * 1000) : new Date(d)
|
|
754
|
-
|
|
755
|
-
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to Date`, {
|
|
756
|
-
input: d,
|
|
757
|
-
})
|
|
758
|
-
|
|
759
|
-
return date
|
|
810
|
+
isValid(input: LocalTimeInputNullable): boolean {
|
|
811
|
+
return this.fromOrNull(input) !== null
|
|
760
812
|
}
|
|
761
813
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
if (d instanceof LocalTime) return d.unix()
|
|
765
|
-
|
|
766
|
-
const date = d instanceof Date ? d : new Date(d)
|
|
767
|
-
|
|
768
|
-
_assert(!isNaN(date.getDate()), `Cannot parse "${d}" to UnixTimestamp`, {
|
|
769
|
-
input: d,
|
|
770
|
-
})
|
|
771
|
-
|
|
772
|
-
return date.valueOf() / 1000
|
|
814
|
+
isValidString(isoString: string | undefined | null): boolean {
|
|
815
|
+
return this.fromStringOrNull(isoString) !== null
|
|
773
816
|
}
|
|
774
817
|
|
|
775
|
-
|
|
776
|
-
|
|
818
|
+
private assertNotNull(
|
|
819
|
+
lt: LocalTime | null,
|
|
820
|
+
input: LocalTimeInputNullable,
|
|
821
|
+
): asserts lt is LocalTime {
|
|
822
|
+
_assert(lt !== null, `Cannot parse "${input}" into LocalTime`, {
|
|
823
|
+
input,
|
|
824
|
+
})
|
|
777
825
|
}
|
|
778
826
|
|
|
779
827
|
/**
|
|
@@ -804,21 +852,15 @@ class LocalTimeFactory {
|
|
|
804
852
|
*
|
|
805
853
|
* `localTime` function will instead return LocalTime of `now` for falsy input.
|
|
806
854
|
*/
|
|
807
|
-
orUndefined(
|
|
808
|
-
return
|
|
855
|
+
orUndefined(input: LocalTimeInputNullable): LocalTime | undefined {
|
|
856
|
+
return input || input === 0 ? this.from(input) : undefined
|
|
809
857
|
}
|
|
810
858
|
|
|
811
859
|
/**
|
|
812
860
|
* Creates a LocalTime from the input, unless it's falsy - then returns LocalTime.now
|
|
813
861
|
*/
|
|
814
|
-
orNow(
|
|
815
|
-
return
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
fromComponents(c: { year: number; month: number } & Partial<DateTimeObject>): LocalTime {
|
|
819
|
-
return new LocalTime(
|
|
820
|
-
new Date(c.year, c.month - 1, c.day || 1, c.hour || 0, c.minute || 0, c.second || 0),
|
|
821
|
-
)
|
|
862
|
+
orNow(input: LocalTimeInputNullable): LocalTime {
|
|
863
|
+
return input || input === 0 ? this.from(input) : this.now()
|
|
822
864
|
}
|
|
823
865
|
|
|
824
866
|
sort(items: LocalTime[], dir: SortDirection = 'asc', mutate = false): LocalTime[] {
|
|
@@ -840,7 +882,7 @@ class LocalTimeFactory {
|
|
|
840
882
|
_assert(items2.length, 'localTime.min called on empty array')
|
|
841
883
|
|
|
842
884
|
return items2
|
|
843
|
-
.map(i => this.
|
|
885
|
+
.map(i => this.from(i))
|
|
844
886
|
.reduce((min, item) => (min.$date.valueOf() <= item.$date.valueOf() ? min : item))
|
|
845
887
|
}
|
|
846
888
|
|
|
@@ -853,7 +895,7 @@ class LocalTimeFactory {
|
|
|
853
895
|
_assert(items2.length, 'localTime.max called on empty array')
|
|
854
896
|
|
|
855
897
|
return items2
|
|
856
|
-
.map(i => this.
|
|
898
|
+
.map(i => this.from(i))
|
|
857
899
|
.reduce((max, item) => (max.$date.valueOf() >= item.$date.valueOf() ? max : item))
|
|
858
900
|
}
|
|
859
901
|
}
|
|
@@ -969,7 +1011,7 @@ interface LocalTimeFn extends LocalTimeFactory {
|
|
|
969
1011
|
|
|
970
1012
|
const localTimeFactory = new LocalTimeFactory()
|
|
971
1013
|
|
|
972
|
-
export const localTime = localTimeFactory.
|
|
1014
|
+
export const localTime = localTimeFactory.from.bind(localTimeFactory) as LocalTimeFn
|
|
973
1015
|
|
|
974
1016
|
// The line below is the blackest of black magic I have ever written in 2024.
|
|
975
1017
|
// And probably 2023 as well.
|
|
@@ -17,10 +17,7 @@ export class TimeInterval {
|
|
|
17
17
|
) {}
|
|
18
18
|
|
|
19
19
|
static of(start: LocalTimeInput, end: LocalTimeInput): TimeInterval {
|
|
20
|
-
return new TimeInterval(
|
|
21
|
-
localTime.parseToUnixTimestamp(start),
|
|
22
|
-
localTime.parseToUnixTimestamp(end),
|
|
23
|
-
)
|
|
20
|
+
return new TimeInterval(localTime.from(start).unix, localTime.from(end).unix)
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
get start(): UnixTimestampNumber {
|
|
@@ -77,7 +74,7 @@ export class TimeInterval {
|
|
|
77
74
|
}
|
|
78
75
|
|
|
79
76
|
includes(d: LocalTimeInput, incl: Inclusiveness = '[)'): boolean {
|
|
80
|
-
d = localTime.
|
|
77
|
+
d = localTime.from(d).unix
|
|
81
78
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
82
79
|
if (d < this.$start || (d === this.$start && incl[0] === '(')) return false
|
|
83
80
|
if (d > this.$end || (d === this.$end && incl[1] === ')')) return false
|
package/src/env/buildInfo.ts
CHANGED
|
@@ -44,11 +44,11 @@ export interface BuildInfo {
|
|
|
44
44
|
|
|
45
45
|
export function generateBuildInfoDev(): BuildInfo {
|
|
46
46
|
const now = localTime.now()
|
|
47
|
-
const ts = now.unix
|
|
47
|
+
const ts = now.unix
|
|
48
48
|
const rev = 'devRev'
|
|
49
49
|
const branchName = 'devBranch'
|
|
50
50
|
const repoName = 'devRepo'
|
|
51
|
-
const tsCommit = now.unix
|
|
51
|
+
const tsCommit = now.unix
|
|
52
52
|
|
|
53
53
|
const ver = [now.toStringCompact(), repoName, branchName, rev].join('_')
|
|
54
54
|
|