@naturalcycles/js-lib 14.91.1 → 14.93.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 +29 -0
- package/dist/datetime/dateInterval.js +60 -0
- package/dist/datetime/localDate.d.ts +6 -1
- package/dist/datetime/localDate.js +16 -0
- package/dist/datetime/localTime.d.ts +9 -1
- package/dist/datetime/localTime.js +140 -80
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist-esm/datetime/dateInterval.js +56 -0
- package/dist-esm/datetime/localDate.js +16 -0
- package/dist-esm/datetime/localTime.js +140 -80
- package/dist-esm/index.js +1 -0
- package/package.json +1 -1
- package/src/datetime/dateInterval.ts +68 -0
- package/src/datetime/localDate.ts +22 -1
- package/src/datetime/localTime.ts +160 -74
- package/src/index.ts +3 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _assert } from '../error/assert'
|
|
2
|
+
import { _ms } from '../time/time.util'
|
|
2
3
|
import { IsoDate, IsoDateTime, UnixTimestamp } from '../types'
|
|
3
4
|
import { LocalDate } from './localDate'
|
|
4
5
|
|
|
@@ -26,11 +27,14 @@ export interface LocalTimeComponents {
|
|
|
26
27
|
// .valueOf returns unix timestamp (no millis)
|
|
27
28
|
// Prevents dayjs(undefined) being dayjs.now()
|
|
28
29
|
// Validates on parse, throws if invalid. Doesn't allow invalid objects
|
|
30
|
+
// No arbitrary .format('') (which is slow to parse) vs well-defined (opinionated) formats
|
|
31
|
+
// Separate LocalTime, powered by native js Date, and LocalDate - a smaller functionality class when
|
|
32
|
+
// you only need "whole dates", no time, no timezone worry
|
|
29
33
|
/**
|
|
30
34
|
* @experimental
|
|
31
35
|
*/
|
|
32
36
|
export class LocalTime {
|
|
33
|
-
private constructor(private $date: Date) {}
|
|
37
|
+
private constructor(private $date: Date, public utcMode: boolean) {}
|
|
34
38
|
|
|
35
39
|
/**
|
|
36
40
|
* Parses input String into LocalDate.
|
|
@@ -46,6 +50,16 @@ export class LocalTime {
|
|
|
46
50
|
return t
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
utc(): this {
|
|
54
|
+
this.utcMode = true
|
|
55
|
+
return this
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
local(): this {
|
|
59
|
+
this.utcMode = false
|
|
60
|
+
return this
|
|
61
|
+
}
|
|
62
|
+
|
|
49
63
|
/**
|
|
50
64
|
* Returns null if invalid
|
|
51
65
|
*/
|
|
@@ -68,63 +82,65 @@ export class LocalTime {
|
|
|
68
82
|
return null
|
|
69
83
|
}
|
|
70
84
|
|
|
71
|
-
|
|
85
|
+
// if (utc) {
|
|
86
|
+
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
87
|
+
// }
|
|
88
|
+
|
|
89
|
+
return new LocalTime(date, false)
|
|
72
90
|
}
|
|
73
91
|
|
|
74
92
|
static isValid(d: LocalTimeConfig): boolean {
|
|
75
93
|
return this.parseOrNull(d) !== null
|
|
76
94
|
}
|
|
77
95
|
|
|
78
|
-
static unix(ts: UnixTimestamp): LocalTime {
|
|
79
|
-
return new LocalTime(new Date(ts * 1000))
|
|
80
|
-
}
|
|
81
|
-
|
|
82
96
|
static now(): LocalTime {
|
|
83
|
-
return
|
|
97
|
+
return new LocalTime(new Date(), false)
|
|
84
98
|
}
|
|
85
99
|
|
|
86
100
|
static fromComponents(
|
|
87
101
|
c: { year: number; month: number } & Partial<LocalTimeComponents>,
|
|
88
102
|
): LocalTime {
|
|
89
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second))
|
|
103
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second), false)
|
|
90
104
|
}
|
|
91
105
|
|
|
92
106
|
get(unit: LocalTimeUnit): number {
|
|
93
107
|
if (unit === 'year') {
|
|
94
|
-
return this.$date.getFullYear()
|
|
108
|
+
return this.utcMode ? this.$date.getUTCFullYear() : this.$date.getFullYear()
|
|
95
109
|
}
|
|
96
110
|
if (unit === 'month') {
|
|
97
|
-
return this.$date.getMonth() + 1
|
|
111
|
+
return (this.utcMode ? this.$date.getUTCMonth() : this.$date.getMonth()) + 1
|
|
98
112
|
}
|
|
99
113
|
if (unit === 'day') {
|
|
100
|
-
return this.$date.getDate()
|
|
114
|
+
return this.utcMode ? this.$date.getUTCDate() : this.$date.getDate()
|
|
101
115
|
}
|
|
102
116
|
if (unit === 'hour') {
|
|
103
|
-
return this.$date.getHours()
|
|
117
|
+
return this.utcMode ? this.$date.getUTCHours() : this.$date.getHours()
|
|
104
118
|
}
|
|
105
119
|
if (unit === 'minute') {
|
|
106
|
-
return this.$date.getMinutes()
|
|
120
|
+
return this.utcMode ? this.$date.getUTCMinutes() : this.$date.getMinutes()
|
|
107
121
|
}
|
|
108
122
|
// second
|
|
109
|
-
return this.$date.getSeconds()
|
|
123
|
+
return this.utcMode ? this.$date.getUTCSeconds() : this.$date.getSeconds()
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
set(unit: LocalTimeUnit, v: number, mutate = false): LocalTime {
|
|
113
127
|
const t = mutate ? this : this.clone()
|
|
114
128
|
|
|
129
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
115
130
|
if (unit === 'year') {
|
|
116
|
-
t.$date.setFullYear(v)
|
|
131
|
+
this.utcMode ? t.$date.setUTCFullYear(v) : t.$date.setFullYear(v)
|
|
117
132
|
} else if (unit === 'month') {
|
|
118
|
-
t.$date.setMonth(v - 1)
|
|
133
|
+
this.utcMode ? t.$date.setUTCMonth(v - 1) : t.$date.setMonth(v - 1)
|
|
119
134
|
} else if (unit === 'day') {
|
|
120
|
-
t.$date.setDate(v)
|
|
135
|
+
this.utcMode ? t.$date.setUTCDate(v) : t.$date.setDate(v)
|
|
121
136
|
} else if (unit === 'hour') {
|
|
122
|
-
t.$date.setHours(v)
|
|
137
|
+
this.utcMode ? t.$date.setUTCHours(v) : t.$date.setHours(v)
|
|
123
138
|
} else if (unit === 'minute') {
|
|
124
|
-
t.$date.setMinutes(v)
|
|
139
|
+
this.utcMode ? t.$date.setUTCMinutes(v) : t.$date.setMinutes(v)
|
|
125
140
|
} else if (unit === 'second') {
|
|
126
|
-
t.$date.setSeconds(v)
|
|
141
|
+
this.utcMode ? t.$date.setUTCSeconds(v) : t.$date.setSeconds(v)
|
|
127
142
|
}
|
|
143
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
128
144
|
|
|
129
145
|
return t
|
|
130
146
|
}
|
|
@@ -132,57 +148,59 @@ export class LocalTime {
|
|
|
132
148
|
year(): number
|
|
133
149
|
year(v: number): LocalTime
|
|
134
150
|
year(v?: number): number | LocalTime {
|
|
135
|
-
return v === undefined ? this
|
|
151
|
+
return v === undefined ? this.get('year') : this.set('year', v)
|
|
136
152
|
}
|
|
137
153
|
month(): number
|
|
138
154
|
month(v: number): LocalTime
|
|
139
155
|
month(v?: number): number | LocalTime {
|
|
140
|
-
return v === undefined ? this
|
|
156
|
+
return v === undefined ? this.get('month') : this.set('month', v)
|
|
141
157
|
}
|
|
142
158
|
date(): number
|
|
143
159
|
date(v: number): LocalTime
|
|
144
160
|
date(v?: number): number | LocalTime {
|
|
145
|
-
return v === undefined ? this
|
|
161
|
+
return v === undefined ? this.get('day') : this.set('day', v)
|
|
146
162
|
}
|
|
147
163
|
hour(): number
|
|
148
164
|
hour(v: number): LocalTime
|
|
149
165
|
hour(v?: number): number | LocalTime {
|
|
150
|
-
return v === undefined ? this
|
|
166
|
+
return v === undefined ? this.get('hour') : this.set('hour', v)
|
|
151
167
|
}
|
|
152
168
|
minute(): number
|
|
153
169
|
minute(v: number): LocalTime
|
|
154
170
|
minute(v?: number): number | LocalTime {
|
|
155
|
-
return v === undefined ? this
|
|
171
|
+
return v === undefined ? this.get('minute') : this.set('minute', v)
|
|
156
172
|
}
|
|
157
173
|
second(): number
|
|
158
174
|
second(v: number): LocalTime
|
|
159
175
|
second(v?: number): number | LocalTime {
|
|
160
|
-
return v === undefined ? this
|
|
176
|
+
return v === undefined ? this.get('second') : this.set('second', v)
|
|
161
177
|
}
|
|
162
178
|
|
|
163
179
|
setComponents(c: Partial<LocalTimeComponents>, mutate = false): LocalTime {
|
|
164
180
|
const d = mutate ? this.$date : new Date(this.$date)
|
|
165
181
|
|
|
182
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
166
183
|
if (c.year) {
|
|
167
|
-
d.setFullYear(c.year)
|
|
184
|
+
this.utcMode ? d.setUTCFullYear(c.year) : d.setFullYear(c.year)
|
|
168
185
|
}
|
|
169
186
|
if (c.month) {
|
|
170
|
-
d.setMonth(c.month - 1)
|
|
187
|
+
this.utcMode ? d.setUTCMonth(c.month - 1) : d.setMonth(c.month - 1)
|
|
171
188
|
}
|
|
172
189
|
if (c.day) {
|
|
173
|
-
d.setDate(c.day)
|
|
190
|
+
this.utcMode ? d.setUTCDate(c.day) : d.setDate(c.day)
|
|
174
191
|
}
|
|
175
192
|
if (c.hour !== undefined) {
|
|
176
|
-
d.setHours(c.hour)
|
|
193
|
+
this.utcMode ? d.setUTCHours(c.hour) : d.setHours(c.hour)
|
|
177
194
|
}
|
|
178
195
|
if (c.minute !== undefined) {
|
|
179
|
-
d.setMinutes(c.minute)
|
|
196
|
+
this.utcMode ? d.setUTCMinutes(c.minute) : d.setMinutes(c.minute)
|
|
180
197
|
}
|
|
181
198
|
if (c.second !== undefined) {
|
|
182
|
-
d.setSeconds(c.second)
|
|
199
|
+
this.utcMode ? d.setUTCSeconds(c.second) : d.setSeconds(c.second)
|
|
183
200
|
}
|
|
201
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
184
202
|
|
|
185
|
-
return mutate ? this : new LocalTime(d)
|
|
203
|
+
return mutate ? this : new LocalTime(d, this.utcMode)
|
|
186
204
|
}
|
|
187
205
|
|
|
188
206
|
add(num: number, unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
@@ -190,7 +208,7 @@ export class LocalTime {
|
|
|
190
208
|
}
|
|
191
209
|
|
|
192
210
|
subtract(num: number, unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
193
|
-
return this.add(-
|
|
211
|
+
return this.add(num * -1, unit, mutate)
|
|
194
212
|
}
|
|
195
213
|
|
|
196
214
|
absDiff(other: LocalTimeConfig, unit: LocalTimeUnit): number {
|
|
@@ -233,36 +251,25 @@ export class LocalTime {
|
|
|
233
251
|
startOf(unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
234
252
|
if (unit === 'second') return this
|
|
235
253
|
|
|
236
|
-
|
|
237
|
-
const d = this.$date
|
|
238
|
-
d.setSeconds(0)
|
|
239
|
-
if (unit === 'minute') return this
|
|
240
|
-
d.setMinutes(0)
|
|
241
|
-
if (unit === 'hour') return this
|
|
242
|
-
d.setHours(0)
|
|
243
|
-
if (unit === 'day') return this
|
|
244
|
-
d.setDate(0)
|
|
245
|
-
if (unit === 'month') return this
|
|
246
|
-
d.setMonth(0)
|
|
247
|
-
return this
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const c = this.components()
|
|
254
|
+
const d = mutate ? this.$date : new Date(this.$date)
|
|
251
255
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
256
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
257
|
+
this.utcMode ? d.setUTCSeconds(0) : d.setSeconds(0)
|
|
258
|
+
if (unit !== 'minute') {
|
|
259
|
+
this.utcMode ? d.setUTCMinutes(0) : d.setMinutes(0)
|
|
260
|
+
if (unit !== 'hour') {
|
|
261
|
+
this.utcMode ? d.setUTCHours(0) : d.setHours(0)
|
|
262
|
+
if (unit !== 'day') {
|
|
263
|
+
this.utcMode ? d.setUTCDate(0) : d.setDate(0)
|
|
264
|
+
if (unit !== 'month') {
|
|
265
|
+
this.utcMode ? d.setUTCMonth(0) : d.setMonth(0)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
263
269
|
}
|
|
270
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
264
271
|
|
|
265
|
-
return LocalTime.
|
|
272
|
+
return mutate ? this : new LocalTime(d, this.utcMode)
|
|
266
273
|
}
|
|
267
274
|
|
|
268
275
|
static sort(items: LocalTime[], mutate = false, descending = false): LocalTime[] {
|
|
@@ -330,6 +337,17 @@ export class LocalTime {
|
|
|
330
337
|
// todo: endOf
|
|
331
338
|
|
|
332
339
|
components(): LocalTimeComponents {
|
|
340
|
+
if (this.utcMode) {
|
|
341
|
+
return {
|
|
342
|
+
year: this.$date.getUTCFullYear(),
|
|
343
|
+
month: this.$date.getUTCMonth() + 1,
|
|
344
|
+
day: this.$date.getUTCDate(),
|
|
345
|
+
hour: this.$date.getUTCHours(),
|
|
346
|
+
minute: this.$date.getUTCMinutes(),
|
|
347
|
+
second: this.$date.getSeconds(),
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
333
351
|
return {
|
|
334
352
|
year: this.$date.getFullYear(),
|
|
335
353
|
month: this.$date.getMonth() + 1,
|
|
@@ -340,23 +358,47 @@ export class LocalTime {
|
|
|
340
358
|
}
|
|
341
359
|
}
|
|
342
360
|
|
|
361
|
+
fromNow(now: LocalTimeConfig = LocalTime.now()): string {
|
|
362
|
+
const msDiff = LocalTime.of(now).unixMillis() - this.unixMillis()
|
|
363
|
+
|
|
364
|
+
if (msDiff === 0) return 'now'
|
|
365
|
+
|
|
366
|
+
if (msDiff >= 0) {
|
|
367
|
+
return `${_ms(msDiff)} ago`
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return `in ${_ms(msDiff * -1)}`
|
|
371
|
+
}
|
|
372
|
+
|
|
343
373
|
getDate(): Date {
|
|
344
374
|
return this.$date
|
|
345
375
|
}
|
|
346
376
|
|
|
347
377
|
clone(): LocalTime {
|
|
348
|
-
return new LocalTime(new Date(this.$date))
|
|
378
|
+
return new LocalTime(new Date(this.$date), this.utcMode)
|
|
349
379
|
}
|
|
350
380
|
|
|
351
381
|
unix(): UnixTimestamp {
|
|
352
382
|
return Math.floor(this.$date.valueOf() / 1000)
|
|
353
383
|
}
|
|
354
384
|
|
|
385
|
+
unixMillis(): number {
|
|
386
|
+
return this.$date.valueOf()
|
|
387
|
+
}
|
|
388
|
+
|
|
355
389
|
valueOf(): UnixTimestamp {
|
|
356
390
|
return Math.floor(this.$date.valueOf() / 1000)
|
|
357
391
|
}
|
|
358
392
|
|
|
359
393
|
toLocalDate(): LocalDate {
|
|
394
|
+
if (this.utcMode) {
|
|
395
|
+
return LocalDate.create(
|
|
396
|
+
this.$date.getUTCFullYear(),
|
|
397
|
+
this.$date.getUTCMonth() + 1,
|
|
398
|
+
this.$date.getUTCDate(),
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
|
|
360
402
|
return LocalDate.create(
|
|
361
403
|
this.$date.getFullYear(),
|
|
362
404
|
this.$date.getMonth() + 1,
|
|
@@ -365,11 +407,29 @@ export class LocalTime {
|
|
|
365
407
|
}
|
|
366
408
|
|
|
367
409
|
toPretty(seconds = true): IsoDateTime {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
410
|
+
const { year, month, day, hour, minute, second } = this.components()
|
|
411
|
+
|
|
412
|
+
return (
|
|
413
|
+
[
|
|
414
|
+
String(year).padStart(4, '0'),
|
|
415
|
+
String(month).padStart(2, '0'),
|
|
416
|
+
String(day).padStart(2, '0'),
|
|
417
|
+
].join('-') +
|
|
418
|
+
' ' +
|
|
419
|
+
[
|
|
420
|
+
String(hour).padStart(2, '0'),
|
|
421
|
+
String(minute).padStart(2, '0'),
|
|
422
|
+
seconds && String(second).padStart(2, '0'),
|
|
423
|
+
]
|
|
424
|
+
.filter(Boolean)
|
|
425
|
+
.join(':')
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
// return this.$date
|
|
429
|
+
// .toISOString()
|
|
430
|
+
// .slice(0, seconds ? 19 : 16)
|
|
431
|
+
// .split('T')
|
|
432
|
+
// .join(' ')
|
|
373
433
|
}
|
|
374
434
|
|
|
375
435
|
/**
|
|
@@ -383,21 +443,47 @@ export class LocalTime {
|
|
|
383
443
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
384
444
|
*/
|
|
385
445
|
toISODate(): IsoDate {
|
|
386
|
-
|
|
446
|
+
const { year, month, day } = this.components()
|
|
447
|
+
|
|
448
|
+
return [
|
|
449
|
+
String(year).padStart(4, '0'),
|
|
450
|
+
String(month).padStart(2, '0'),
|
|
451
|
+
String(day).padStart(2, '0'),
|
|
452
|
+
].join('-')
|
|
453
|
+
|
|
454
|
+
// return this.$date.toISOString().slice(0, 10)
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
459
|
+
*/
|
|
460
|
+
toISOTime(seconds = true): string {
|
|
461
|
+
// return this.$date.toISOString().slice(11, seconds ? 19 : 16)
|
|
462
|
+
const { hour, minute, second } = this.components()
|
|
463
|
+
|
|
464
|
+
return [
|
|
465
|
+
String(hour).padStart(2, '0'),
|
|
466
|
+
String(minute).padStart(2, '0'),
|
|
467
|
+
seconds && String(second).padStart(2, '0'),
|
|
468
|
+
]
|
|
469
|
+
.filter(Boolean)
|
|
470
|
+
.join(':')
|
|
387
471
|
}
|
|
388
472
|
|
|
389
473
|
/**
|
|
390
474
|
* Returns e.g: `19840621_1705`
|
|
391
475
|
*/
|
|
392
476
|
toStringCompact(seconds = false): string {
|
|
477
|
+
const { year, month, day, hour, minute, second } = this.components()
|
|
478
|
+
|
|
393
479
|
return [
|
|
394
|
-
String(
|
|
395
|
-
String(
|
|
396
|
-
String(
|
|
480
|
+
String(year).padStart(4, '0'),
|
|
481
|
+
String(month).padStart(2, '0'),
|
|
482
|
+
String(day).padStart(2, '0'),
|
|
397
483
|
'_',
|
|
398
|
-
String(
|
|
399
|
-
String(
|
|
400
|
-
seconds ? String(
|
|
484
|
+
String(hour).padStart(2, '0'),
|
|
485
|
+
String(minute).padStart(2, '0'),
|
|
486
|
+
seconds ? String(second).padStart(2, '0') : '',
|
|
401
487
|
].join('')
|
|
402
488
|
}
|
|
403
489
|
|
package/src/index.ts
CHANGED
|
@@ -158,10 +158,13 @@ export * from './math/stack.util'
|
|
|
158
158
|
export * from './string/leven'
|
|
159
159
|
export * from './datetime/localDate'
|
|
160
160
|
export * from './datetime/localTime'
|
|
161
|
+
export * from './datetime/dateInterval'
|
|
161
162
|
import { LocalDateConfig, LocalDateUnit } from './datetime/localDate'
|
|
162
163
|
import { LocalTimeConfig, LocalTimeUnit, LocalTimeComponents } from './datetime/localTime'
|
|
164
|
+
import { DateIntervalConfig } from './datetime/dateInterval'
|
|
163
165
|
|
|
164
166
|
export type {
|
|
167
|
+
DateIntervalConfig,
|
|
165
168
|
LocalDateConfig,
|
|
166
169
|
LocalDateUnit,
|
|
167
170
|
LocalTimeConfig,
|