@naturalcycles/js-lib 14.91.0 → 14.92.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/localDate.d.ts +8 -1
- package/dist/datetime/localDate.js +20 -0
- package/dist/datetime/localTime.d.ts +20 -3
- package/dist/datetime/localTime.js +151 -81
- package/dist-esm/datetime/localDate.js +20 -0
- package/dist-esm/datetime/localTime.js +151 -81
- package/package.json +1 -1
- package/src/datetime/localDate.ts +27 -1
- package/src/datetime/localTime.ts +178 -76
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { _assert } from '../error/assert';
|
|
2
|
+
import { _ms } from '../time/time.util';
|
|
3
|
+
import { LocalDate } from './localDate';
|
|
2
4
|
/* eslint-disable no-dupe-class-members */
|
|
3
5
|
// Design choices:
|
|
4
6
|
// No milliseconds
|
|
@@ -13,8 +15,9 @@ import { _assert } from '../error/assert';
|
|
|
13
15
|
* @experimental
|
|
14
16
|
*/
|
|
15
17
|
export class LocalTime {
|
|
16
|
-
constructor($date) {
|
|
18
|
+
constructor($date, utcMode) {
|
|
17
19
|
this.$date = $date;
|
|
20
|
+
this.utcMode = utcMode;
|
|
18
21
|
}
|
|
19
22
|
/**
|
|
20
23
|
* Parses input String into LocalDate.
|
|
@@ -27,6 +30,14 @@ export class LocalTime {
|
|
|
27
30
|
}
|
|
28
31
|
return t;
|
|
29
32
|
}
|
|
33
|
+
utc() {
|
|
34
|
+
this.utcMode = true;
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
local() {
|
|
38
|
+
this.utcMode = false;
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
30
41
|
/**
|
|
31
42
|
* Returns null if invalid
|
|
32
43
|
*/
|
|
@@ -48,106 +59,110 @@ export class LocalTime {
|
|
|
48
59
|
// throw new TypeError(`Cannot parse "${d}" into LocalTime`)
|
|
49
60
|
return null;
|
|
50
61
|
}
|
|
51
|
-
|
|
62
|
+
// if (utc) {
|
|
63
|
+
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
64
|
+
// }
|
|
65
|
+
return new LocalTime(date, false);
|
|
52
66
|
}
|
|
53
67
|
static isValid(d) {
|
|
54
68
|
return this.parseOrNull(d) !== null;
|
|
55
69
|
}
|
|
56
|
-
static unix(ts) {
|
|
57
|
-
return new LocalTime(new Date(ts * 1000));
|
|
58
|
-
}
|
|
59
70
|
static now() {
|
|
60
|
-
return
|
|
71
|
+
return new LocalTime(new Date(), false);
|
|
61
72
|
}
|
|
62
73
|
static fromComponents(c) {
|
|
63
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second));
|
|
74
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second), false);
|
|
64
75
|
}
|
|
65
76
|
get(unit) {
|
|
66
77
|
if (unit === 'year') {
|
|
67
|
-
return this.$date.getFullYear();
|
|
78
|
+
return this.utcMode ? this.$date.getUTCFullYear() : this.$date.getFullYear();
|
|
68
79
|
}
|
|
69
80
|
if (unit === 'month') {
|
|
70
|
-
return this.$date.getMonth() + 1;
|
|
81
|
+
return (this.utcMode ? this.$date.getUTCMonth() : this.$date.getMonth()) + 1;
|
|
71
82
|
}
|
|
72
83
|
if (unit === 'day') {
|
|
73
|
-
return this.$date.getDate();
|
|
84
|
+
return this.utcMode ? this.$date.getUTCDate() : this.$date.getDate();
|
|
74
85
|
}
|
|
75
86
|
if (unit === 'hour') {
|
|
76
|
-
return this.$date.getHours();
|
|
87
|
+
return this.utcMode ? this.$date.getUTCHours() : this.$date.getHours();
|
|
77
88
|
}
|
|
78
89
|
if (unit === 'minute') {
|
|
79
|
-
return this.$date.getMinutes();
|
|
90
|
+
return this.utcMode ? this.$date.getUTCMinutes() : this.$date.getMinutes();
|
|
80
91
|
}
|
|
81
92
|
// second
|
|
82
|
-
return this.$date.getSeconds();
|
|
93
|
+
return this.utcMode ? this.$date.getUTCSeconds() : this.$date.getSeconds();
|
|
83
94
|
}
|
|
84
95
|
set(unit, v, mutate = false) {
|
|
85
96
|
const t = mutate ? this : this.clone();
|
|
97
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
86
98
|
if (unit === 'year') {
|
|
87
|
-
t.$date.setFullYear(v);
|
|
99
|
+
this.utcMode ? t.$date.setUTCFullYear(v) : t.$date.setFullYear(v);
|
|
88
100
|
}
|
|
89
101
|
else if (unit === 'month') {
|
|
90
|
-
t.$date.setMonth(v - 1);
|
|
102
|
+
this.utcMode ? t.$date.setUTCMonth(v - 1) : t.$date.setMonth(v - 1);
|
|
91
103
|
}
|
|
92
104
|
else if (unit === 'day') {
|
|
93
|
-
t.$date.setDate(v);
|
|
105
|
+
this.utcMode ? t.$date.setUTCDate(v) : t.$date.setDate(v);
|
|
94
106
|
}
|
|
95
107
|
else if (unit === 'hour') {
|
|
96
|
-
t.$date.setHours(v);
|
|
108
|
+
this.utcMode ? t.$date.setUTCHours(v) : t.$date.setHours(v);
|
|
97
109
|
}
|
|
98
110
|
else if (unit === 'minute') {
|
|
99
|
-
t.$date.setMinutes(v);
|
|
111
|
+
this.utcMode ? t.$date.setUTCMinutes(v) : t.$date.setMinutes(v);
|
|
100
112
|
}
|
|
101
113
|
else if (unit === 'second') {
|
|
102
|
-
t.$date.setSeconds(v);
|
|
114
|
+
this.utcMode ? t.$date.setUTCSeconds(v) : t.$date.setSeconds(v);
|
|
103
115
|
}
|
|
116
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
104
117
|
return t;
|
|
105
118
|
}
|
|
106
119
|
year(v) {
|
|
107
|
-
return v === undefined ? this
|
|
120
|
+
return v === undefined ? this.get('year') : this.set('year', v);
|
|
108
121
|
}
|
|
109
122
|
month(v) {
|
|
110
|
-
return v === undefined ? this
|
|
123
|
+
return v === undefined ? this.get('month') : this.set('month', v);
|
|
111
124
|
}
|
|
112
125
|
date(v) {
|
|
113
|
-
return v === undefined ? this
|
|
126
|
+
return v === undefined ? this.get('day') : this.set('day', v);
|
|
114
127
|
}
|
|
115
128
|
hour(v) {
|
|
116
|
-
return v === undefined ? this
|
|
129
|
+
return v === undefined ? this.get('hour') : this.set('hour', v);
|
|
117
130
|
}
|
|
118
131
|
minute(v) {
|
|
119
|
-
return v === undefined ? this
|
|
132
|
+
return v === undefined ? this.get('minute') : this.set('minute', v);
|
|
120
133
|
}
|
|
121
134
|
second(v) {
|
|
122
|
-
return v === undefined ? this
|
|
135
|
+
return v === undefined ? this.get('second') : this.set('second', v);
|
|
123
136
|
}
|
|
124
137
|
setComponents(c, mutate = false) {
|
|
125
138
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
139
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
126
140
|
if (c.year) {
|
|
127
|
-
d.setFullYear(c.year);
|
|
141
|
+
this.utcMode ? d.setUTCFullYear(c.year) : d.setFullYear(c.year);
|
|
128
142
|
}
|
|
129
143
|
if (c.month) {
|
|
130
|
-
d.setMonth(c.month - 1);
|
|
144
|
+
this.utcMode ? d.setUTCMonth(c.month - 1) : d.setMonth(c.month - 1);
|
|
131
145
|
}
|
|
132
146
|
if (c.day) {
|
|
133
|
-
d.setDate(c.day);
|
|
147
|
+
this.utcMode ? d.setUTCDate(c.day) : d.setDate(c.day);
|
|
134
148
|
}
|
|
135
149
|
if (c.hour !== undefined) {
|
|
136
|
-
d.setHours(c.hour);
|
|
150
|
+
this.utcMode ? d.setUTCHours(c.hour) : d.setHours(c.hour);
|
|
137
151
|
}
|
|
138
152
|
if (c.minute !== undefined) {
|
|
139
|
-
d.setMinutes(c.minute);
|
|
153
|
+
this.utcMode ? d.setUTCMinutes(c.minute) : d.setMinutes(c.minute);
|
|
140
154
|
}
|
|
141
155
|
if (c.second !== undefined) {
|
|
142
|
-
d.setSeconds(c.second);
|
|
156
|
+
this.utcMode ? d.setUTCSeconds(c.second) : d.setSeconds(c.second);
|
|
143
157
|
}
|
|
144
|
-
|
|
158
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
159
|
+
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
145
160
|
}
|
|
146
161
|
add(num, unit, mutate = false) {
|
|
147
162
|
return this.set(unit, this.get(unit) + num, mutate);
|
|
148
163
|
}
|
|
149
164
|
subtract(num, unit, mutate = false) {
|
|
150
|
-
return this.add(-
|
|
165
|
+
return this.add(num * -1, unit, mutate);
|
|
151
166
|
}
|
|
152
167
|
absDiff(other, unit) {
|
|
153
168
|
return Math.abs(this.diff(other, unit));
|
|
@@ -185,40 +200,23 @@ export class LocalTime {
|
|
|
185
200
|
startOf(unit, mutate = false) {
|
|
186
201
|
if (unit === 'second')
|
|
187
202
|
return this;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const c = this.components();
|
|
206
|
-
c.second = 0;
|
|
207
|
-
if (unit === 'year') {
|
|
208
|
-
c.month = c.day = 1;
|
|
209
|
-
c.hour = c.minute = 0;
|
|
210
|
-
}
|
|
211
|
-
else if (unit === 'month') {
|
|
212
|
-
c.day = 1;
|
|
213
|
-
c.hour = c.minute = 0;
|
|
214
|
-
}
|
|
215
|
-
else if (unit === 'day') {
|
|
216
|
-
c.hour = c.minute = 0;
|
|
217
|
-
}
|
|
218
|
-
else if (unit === 'hour') {
|
|
219
|
-
c.minute = 0;
|
|
220
|
-
}
|
|
221
|
-
return LocalTime.fromComponents(c);
|
|
203
|
+
const d = mutate ? this.$date : new Date(this.$date);
|
|
204
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
205
|
+
this.utcMode ? d.setUTCSeconds(0) : d.setSeconds(0);
|
|
206
|
+
if (unit !== 'minute') {
|
|
207
|
+
this.utcMode ? d.setUTCMinutes(0) : d.setMinutes(0);
|
|
208
|
+
if (unit !== 'hour') {
|
|
209
|
+
this.utcMode ? d.setUTCHours(0) : d.setHours(0);
|
|
210
|
+
if (unit !== 'day') {
|
|
211
|
+
this.utcMode ? d.setUTCDate(0) : d.setDate(0);
|
|
212
|
+
if (unit !== 'month') {
|
|
213
|
+
this.utcMode ? d.setUTCMonth(0) : d.setMonth(0);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
219
|
+
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
222
220
|
}
|
|
223
221
|
static sort(items, mutate = false, descending = false) {
|
|
224
222
|
const mod = descending ? -1 : 1;
|
|
@@ -273,6 +271,16 @@ export class LocalTime {
|
|
|
273
271
|
}
|
|
274
272
|
// todo: endOf
|
|
275
273
|
components() {
|
|
274
|
+
if (this.utcMode) {
|
|
275
|
+
return {
|
|
276
|
+
year: this.$date.getUTCFullYear(),
|
|
277
|
+
month: this.$date.getUTCMonth() + 1,
|
|
278
|
+
day: this.$date.getUTCDate(),
|
|
279
|
+
hour: this.$date.getUTCHours(),
|
|
280
|
+
minute: this.$date.getUTCMinutes(),
|
|
281
|
+
second: this.$date.getSeconds(),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
276
284
|
return {
|
|
277
285
|
year: this.$date.getFullYear(),
|
|
278
286
|
month: this.$date.getMonth() + 1,
|
|
@@ -282,40 +290,102 @@ export class LocalTime {
|
|
|
282
290
|
second: this.$date.getSeconds(),
|
|
283
291
|
};
|
|
284
292
|
}
|
|
293
|
+
fromNow(now = LocalTime.now()) {
|
|
294
|
+
const msDiff = LocalTime.of(now).unixMillis() - this.unixMillis();
|
|
295
|
+
if (msDiff === 0)
|
|
296
|
+
return 'now';
|
|
297
|
+
if (msDiff >= 0) {
|
|
298
|
+
return `${_ms(msDiff)} ago`;
|
|
299
|
+
}
|
|
300
|
+
return `in ${_ms(msDiff * -1)}`;
|
|
301
|
+
}
|
|
285
302
|
getDate() {
|
|
286
303
|
return this.$date;
|
|
287
304
|
}
|
|
288
305
|
clone() {
|
|
289
|
-
return new LocalTime(new Date(this.$date));
|
|
306
|
+
return new LocalTime(new Date(this.$date), this.utcMode);
|
|
290
307
|
}
|
|
291
308
|
unix() {
|
|
292
309
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
293
310
|
}
|
|
311
|
+
unixMillis() {
|
|
312
|
+
return this.$date.valueOf();
|
|
313
|
+
}
|
|
294
314
|
valueOf() {
|
|
295
315
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
296
316
|
}
|
|
297
|
-
|
|
298
|
-
|
|
317
|
+
toLocalDate() {
|
|
318
|
+
if (this.utcMode) {
|
|
319
|
+
return LocalDate.create(this.$date.getUTCFullYear(), this.$date.getUTCMonth() + 1, this.$date.getUTCDate());
|
|
320
|
+
}
|
|
321
|
+
return LocalDate.create(this.$date.getFullYear(), this.$date.getMonth() + 1, this.$date.getDate());
|
|
299
322
|
}
|
|
300
323
|
toPretty(seconds = true) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
.
|
|
304
|
-
.
|
|
305
|
-
.
|
|
324
|
+
const { year, month, day, hour, minute, second } = this.components();
|
|
325
|
+
return ([
|
|
326
|
+
String(year).padStart(4, '0'),
|
|
327
|
+
String(month).padStart(2, '0'),
|
|
328
|
+
String(day).padStart(2, '0'),
|
|
329
|
+
].join('-') +
|
|
330
|
+
' ' +
|
|
331
|
+
[
|
|
332
|
+
String(hour).padStart(2, '0'),
|
|
333
|
+
String(minute).padStart(2, '0'),
|
|
334
|
+
seconds && String(second).padStart(2, '0'),
|
|
335
|
+
]
|
|
336
|
+
.filter(Boolean)
|
|
337
|
+
.join(':'));
|
|
338
|
+
// return this.$date
|
|
339
|
+
// .toISOString()
|
|
340
|
+
// .slice(0, seconds ? 19 : 16)
|
|
341
|
+
// .split('T')
|
|
342
|
+
// .join(' ')
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Returns e.g: `1984-06-21T17:56:21`, only the date part of DateTime
|
|
346
|
+
*/
|
|
347
|
+
toISODateTime() {
|
|
348
|
+
return this.$date.toISOString().slice(0, 19);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
352
|
+
*/
|
|
353
|
+
toISODate() {
|
|
354
|
+
const { year, month, day } = this.components();
|
|
355
|
+
return [
|
|
356
|
+
String(year).padStart(4, '0'),
|
|
357
|
+
String(month).padStart(2, '0'),
|
|
358
|
+
String(day).padStart(2, '0'),
|
|
359
|
+
].join('-');
|
|
360
|
+
// return this.$date.toISOString().slice(0, 10)
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
364
|
+
*/
|
|
365
|
+
toISOTime(seconds = true) {
|
|
366
|
+
// return this.$date.toISOString().slice(11, seconds ? 19 : 16)
|
|
367
|
+
const { hour, minute, second } = this.components();
|
|
368
|
+
return [
|
|
369
|
+
String(hour).padStart(2, '0'),
|
|
370
|
+
String(minute).padStart(2, '0'),
|
|
371
|
+
seconds && String(second).padStart(2, '0'),
|
|
372
|
+
]
|
|
373
|
+
.filter(Boolean)
|
|
374
|
+
.join(':');
|
|
306
375
|
}
|
|
307
376
|
/**
|
|
308
377
|
* Returns e.g: `19840621_1705`
|
|
309
378
|
*/
|
|
310
379
|
toStringCompact(seconds = false) {
|
|
380
|
+
const { year, month, day, hour, minute, second } = this.components();
|
|
311
381
|
return [
|
|
312
|
-
String(
|
|
313
|
-
String(
|
|
314
|
-
String(
|
|
382
|
+
String(year).padStart(4, '0'),
|
|
383
|
+
String(month).padStart(2, '0'),
|
|
384
|
+
String(day).padStart(2, '0'),
|
|
315
385
|
'_',
|
|
316
|
-
String(
|
|
317
|
-
String(
|
|
318
|
-
seconds ? String(
|
|
386
|
+
String(hour).padStart(2, '0'),
|
|
387
|
+
String(minute).padStart(2, '0'),
|
|
388
|
+
seconds ? String(second).padStart(2, '0') : '',
|
|
319
389
|
].join('');
|
|
320
390
|
}
|
|
321
391
|
toString() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _assert } from '../error/assert'
|
|
2
2
|
import { Sequence } from '../seq/seq'
|
|
3
|
-
import { END, IsoDate } from '../types'
|
|
3
|
+
import { END, IsoDate, UnixTimestamp } from '../types'
|
|
4
|
+
import { LocalTime } from './localTime'
|
|
4
5
|
|
|
5
6
|
export type LocalDateUnit = 'year' | 'month' | 'day'
|
|
6
7
|
|
|
@@ -46,6 +47,10 @@ export class LocalDate {
|
|
|
46
47
|
return new LocalDate(d.getFullYear(), d.getMonth() + 1, d.getDate())
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
static fromDateUTC(d: Date): LocalDate {
|
|
51
|
+
return new LocalDate(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate())
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
/**
|
|
50
55
|
* Returns null if invalid.
|
|
51
56
|
*/
|
|
@@ -78,6 +83,10 @@ export class LocalDate {
|
|
|
78
83
|
return this.fromDate(new Date())
|
|
79
84
|
}
|
|
80
85
|
|
|
86
|
+
static todayUTC(): LocalDate {
|
|
87
|
+
return this.fromDateUTC(new Date())
|
|
88
|
+
}
|
|
89
|
+
|
|
81
90
|
static sort(items: LocalDate[], mutate = false, descending = false): LocalDate[] {
|
|
82
91
|
const mod = descending ? -1 : 1
|
|
83
92
|
return (mutate ? items : [...items]).sort((a, b) => a.cmp(b) * mod)
|
|
@@ -356,6 +365,14 @@ export class LocalDate {
|
|
|
356
365
|
return new Date(this.year, this.month - 1, this.day)
|
|
357
366
|
}
|
|
358
367
|
|
|
368
|
+
toLocalTime(): LocalTime {
|
|
369
|
+
return LocalTime.of(this.toDate())
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
toISODate(): IsoDate {
|
|
373
|
+
return this.toString()
|
|
374
|
+
}
|
|
375
|
+
|
|
359
376
|
toString(): IsoDate {
|
|
360
377
|
return [
|
|
361
378
|
String(this.year).padStart(4, '0'),
|
|
@@ -372,6 +389,15 @@ export class LocalDate {
|
|
|
372
389
|
].join('')
|
|
373
390
|
}
|
|
374
391
|
|
|
392
|
+
// May be not optimal, as LocalTime better suits it
|
|
393
|
+
unix(): UnixTimestamp {
|
|
394
|
+
return Math.floor(this.toDate().valueOf() / 1000)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
unixMillis(): number {
|
|
398
|
+
return this.toDate().valueOf()
|
|
399
|
+
}
|
|
400
|
+
|
|
375
401
|
toJSON(): IsoDate {
|
|
376
402
|
return this.toString()
|
|
377
403
|
}
|