@naturalcycles/js-lib 14.91.2 → 14.94.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 +38 -0
- package/dist/datetime/dateInterval.js +80 -0
- package/dist/datetime/localDate.d.ts +4 -0
- package/dist/datetime/localDate.js +15 -0
- package/dist/datetime/localTime.d.ts +10 -2
- package/dist/datetime/localTime.js +146 -80
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -0
- package/dist-esm/datetime/dateInterval.js +76 -0
- package/dist-esm/datetime/localDate.js +15 -0
- package/dist-esm/datetime/localTime.js +146 -80
- package/dist-esm/index.js +1 -0
- package/package.json +1 -1
- package/src/datetime/dateInterval.ts +91 -0
- package/src/datetime/localDate.ts +17 -0
- package/src/datetime/localTime.ts +165 -75
- package/src/index.ts +5 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _assert } from '../error/assert'
|
|
2
|
+
import { _ms } from '../time/time.util'
|
|
2
3
|
import { IsoDate, IsoDateTime, UnixTimestamp } from '../types'
|
|
3
|
-
import { LocalDate } from './localDate'
|
|
4
|
+
import { Inclusiveness, LocalDate } from './localDate'
|
|
4
5
|
|
|
5
6
|
export type LocalTimeUnit = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second'
|
|
6
7
|
|
|
@@ -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[] {
|
|
@@ -315,6 +322,14 @@ export class LocalTime {
|
|
|
315
322
|
return this.cmp(d) >= 0
|
|
316
323
|
}
|
|
317
324
|
|
|
325
|
+
isBetween(min: LocalTimeConfig, max: LocalTimeConfig, incl: Inclusiveness = '[)'): boolean {
|
|
326
|
+
let r = this.cmp(min)
|
|
327
|
+
if (r < 0 || (r === 0 && incl[0] === '(')) return false
|
|
328
|
+
r = this.cmp(max)
|
|
329
|
+
if (r > 0 || (r === 0 && incl[1] === ')')) return false
|
|
330
|
+
return true
|
|
331
|
+
}
|
|
332
|
+
|
|
318
333
|
/**
|
|
319
334
|
* Returns 1 if this > d
|
|
320
335
|
* returns 0 if they are equal
|
|
@@ -330,6 +345,17 @@ export class LocalTime {
|
|
|
330
345
|
// todo: endOf
|
|
331
346
|
|
|
332
347
|
components(): LocalTimeComponents {
|
|
348
|
+
if (this.utcMode) {
|
|
349
|
+
return {
|
|
350
|
+
year: this.$date.getUTCFullYear(),
|
|
351
|
+
month: this.$date.getUTCMonth() + 1,
|
|
352
|
+
day: this.$date.getUTCDate(),
|
|
353
|
+
hour: this.$date.getUTCHours(),
|
|
354
|
+
minute: this.$date.getUTCMinutes(),
|
|
355
|
+
second: this.$date.getSeconds(),
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
333
359
|
return {
|
|
334
360
|
year: this.$date.getFullYear(),
|
|
335
361
|
month: this.$date.getMonth() + 1,
|
|
@@ -340,12 +366,24 @@ export class LocalTime {
|
|
|
340
366
|
}
|
|
341
367
|
}
|
|
342
368
|
|
|
369
|
+
fromNow(now: LocalTimeConfig = LocalTime.now()): string {
|
|
370
|
+
const msDiff = LocalTime.of(now).unixMillis() - this.unixMillis()
|
|
371
|
+
|
|
372
|
+
if (msDiff === 0) return 'now'
|
|
373
|
+
|
|
374
|
+
if (msDiff >= 0) {
|
|
375
|
+
return `${_ms(msDiff)} ago`
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return `in ${_ms(msDiff * -1)}`
|
|
379
|
+
}
|
|
380
|
+
|
|
343
381
|
getDate(): Date {
|
|
344
382
|
return this.$date
|
|
345
383
|
}
|
|
346
384
|
|
|
347
385
|
clone(): LocalTime {
|
|
348
|
-
return new LocalTime(new Date(this.$date))
|
|
386
|
+
return new LocalTime(new Date(this.$date), this.utcMode)
|
|
349
387
|
}
|
|
350
388
|
|
|
351
389
|
unix(): UnixTimestamp {
|
|
@@ -361,6 +399,14 @@ export class LocalTime {
|
|
|
361
399
|
}
|
|
362
400
|
|
|
363
401
|
toLocalDate(): LocalDate {
|
|
402
|
+
if (this.utcMode) {
|
|
403
|
+
return LocalDate.create(
|
|
404
|
+
this.$date.getUTCFullYear(),
|
|
405
|
+
this.$date.getUTCMonth() + 1,
|
|
406
|
+
this.$date.getUTCDate(),
|
|
407
|
+
)
|
|
408
|
+
}
|
|
409
|
+
|
|
364
410
|
return LocalDate.create(
|
|
365
411
|
this.$date.getFullYear(),
|
|
366
412
|
this.$date.getMonth() + 1,
|
|
@@ -369,11 +415,29 @@ export class LocalTime {
|
|
|
369
415
|
}
|
|
370
416
|
|
|
371
417
|
toPretty(seconds = true): IsoDateTime {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
418
|
+
const { year, month, day, hour, minute, second } = this.components()
|
|
419
|
+
|
|
420
|
+
return (
|
|
421
|
+
[
|
|
422
|
+
String(year).padStart(4, '0'),
|
|
423
|
+
String(month).padStart(2, '0'),
|
|
424
|
+
String(day).padStart(2, '0'),
|
|
425
|
+
].join('-') +
|
|
426
|
+
' ' +
|
|
427
|
+
[
|
|
428
|
+
String(hour).padStart(2, '0'),
|
|
429
|
+
String(minute).padStart(2, '0'),
|
|
430
|
+
seconds && String(second).padStart(2, '0'),
|
|
431
|
+
]
|
|
432
|
+
.filter(Boolean)
|
|
433
|
+
.join(':')
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
// return this.$date
|
|
437
|
+
// .toISOString()
|
|
438
|
+
// .slice(0, seconds ? 19 : 16)
|
|
439
|
+
// .split('T')
|
|
440
|
+
// .join(' ')
|
|
377
441
|
}
|
|
378
442
|
|
|
379
443
|
/**
|
|
@@ -387,21 +451,47 @@ export class LocalTime {
|
|
|
387
451
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
388
452
|
*/
|
|
389
453
|
toISODate(): IsoDate {
|
|
390
|
-
|
|
454
|
+
const { year, month, day } = this.components()
|
|
455
|
+
|
|
456
|
+
return [
|
|
457
|
+
String(year).padStart(4, '0'),
|
|
458
|
+
String(month).padStart(2, '0'),
|
|
459
|
+
String(day).padStart(2, '0'),
|
|
460
|
+
].join('-')
|
|
461
|
+
|
|
462
|
+
// return this.$date.toISOString().slice(0, 10)
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
467
|
+
*/
|
|
468
|
+
toISOTime(seconds = true): string {
|
|
469
|
+
// return this.$date.toISOString().slice(11, seconds ? 19 : 16)
|
|
470
|
+
const { hour, minute, second } = this.components()
|
|
471
|
+
|
|
472
|
+
return [
|
|
473
|
+
String(hour).padStart(2, '0'),
|
|
474
|
+
String(minute).padStart(2, '0'),
|
|
475
|
+
seconds && String(second).padStart(2, '0'),
|
|
476
|
+
]
|
|
477
|
+
.filter(Boolean)
|
|
478
|
+
.join(':')
|
|
391
479
|
}
|
|
392
480
|
|
|
393
481
|
/**
|
|
394
482
|
* Returns e.g: `19840621_1705`
|
|
395
483
|
*/
|
|
396
484
|
toStringCompact(seconds = false): string {
|
|
485
|
+
const { year, month, day, hour, minute, second } = this.components()
|
|
486
|
+
|
|
397
487
|
return [
|
|
398
|
-
String(
|
|
399
|
-
String(
|
|
400
|
-
String(
|
|
488
|
+
String(year).padStart(4, '0'),
|
|
489
|
+
String(month).padStart(2, '0'),
|
|
490
|
+
String(day).padStart(2, '0'),
|
|
401
491
|
'_',
|
|
402
|
-
String(
|
|
403
|
-
String(
|
|
404
|
-
seconds ? String(
|
|
492
|
+
String(hour).padStart(2, '0'),
|
|
493
|
+
String(minute).padStart(2, '0'),
|
|
494
|
+
seconds ? String(second).padStart(2, '0') : '',
|
|
405
495
|
].join('')
|
|
406
496
|
}
|
|
407
497
|
|
package/src/index.ts
CHANGED
|
@@ -158,12 +158,16 @@ export * from './math/stack.util'
|
|
|
158
158
|
export * from './string/leven'
|
|
159
159
|
export * from './datetime/localDate'
|
|
160
160
|
export * from './datetime/localTime'
|
|
161
|
-
|
|
161
|
+
export * from './datetime/dateInterval'
|
|
162
|
+
import { LocalDateConfig, LocalDateUnit, Inclusiveness } 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,
|
|
170
|
+
Inclusiveness,
|
|
167
171
|
LocalTimeConfig,
|
|
168
172
|
LocalTimeUnit,
|
|
169
173
|
LocalTimeComponents,
|