@naturalcycles/js-lib 14.91.2 → 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 +2 -0
- package/dist/datetime/localDate.js +6 -0
- package/dist/datetime/localTime.d.ts +8 -1
- package/dist/datetime/localTime.js +134 -80
- package/dist-esm/datetime/localDate.js +6 -0
- package/dist-esm/datetime/localTime.js +134 -80
- package/package.json +1 -1
- package/src/datetime/localDate.ts +8 -0
- package/src/datetime/localTime.ts +153 -74
|
@@ -19,12 +19,14 @@ export declare class LocalDate {
|
|
|
19
19
|
static of(d: LocalDateConfig): LocalDate;
|
|
20
20
|
static parseCompact(d: string): LocalDate;
|
|
21
21
|
static fromDate(d: Date): LocalDate;
|
|
22
|
+
static fromDateUTC(d: Date): LocalDate;
|
|
22
23
|
/**
|
|
23
24
|
* Returns null if invalid.
|
|
24
25
|
*/
|
|
25
26
|
static parseOrNull(d: LocalDateConfig): LocalDate | null;
|
|
26
27
|
static isValid(iso: string): boolean;
|
|
27
28
|
static today(): LocalDate;
|
|
29
|
+
static todayUTC(): LocalDate;
|
|
28
30
|
static sort(items: LocalDate[], mutate?: boolean, descending?: boolean): LocalDate[];
|
|
29
31
|
static earliestOrUndefined(items: LocalDate[]): LocalDate | undefined;
|
|
30
32
|
static earliest(items: LocalDate[]): LocalDate;
|
|
@@ -39,6 +39,9 @@ class LocalDate {
|
|
|
39
39
|
static fromDate(d) {
|
|
40
40
|
return new LocalDate(d.getFullYear(), d.getMonth() + 1, d.getDate());
|
|
41
41
|
}
|
|
42
|
+
static fromDateUTC(d) {
|
|
43
|
+
return new LocalDate(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate());
|
|
44
|
+
}
|
|
42
45
|
/**
|
|
43
46
|
* Returns null if invalid.
|
|
44
47
|
*/
|
|
@@ -64,6 +67,9 @@ class LocalDate {
|
|
|
64
67
|
static today() {
|
|
65
68
|
return this.fromDate(new Date());
|
|
66
69
|
}
|
|
70
|
+
static todayUTC() {
|
|
71
|
+
return this.fromDateUTC(new Date());
|
|
72
|
+
}
|
|
67
73
|
static sort(items, mutate = false, descending = false) {
|
|
68
74
|
const mod = descending ? -1 : 1;
|
|
69
75
|
return (mutate ? items : [...items]).sort((a, b) => a.cmp(b) * mod);
|
|
@@ -15,18 +15,20 @@ export interface LocalTimeComponents {
|
|
|
15
15
|
*/
|
|
16
16
|
export declare class LocalTime {
|
|
17
17
|
private $date;
|
|
18
|
+
utcMode: boolean;
|
|
18
19
|
private constructor();
|
|
19
20
|
/**
|
|
20
21
|
* Parses input String into LocalDate.
|
|
21
22
|
* Input can already be a LocalDate - it is returned as-is in that case.
|
|
22
23
|
*/
|
|
23
24
|
static of(d: LocalTimeConfig): LocalTime;
|
|
25
|
+
utc(): this;
|
|
26
|
+
local(): this;
|
|
24
27
|
/**
|
|
25
28
|
* Returns null if invalid
|
|
26
29
|
*/
|
|
27
30
|
static parseOrNull(d: LocalTimeConfig): LocalTime | null;
|
|
28
31
|
static isValid(d: LocalTimeConfig): boolean;
|
|
29
|
-
static unix(ts: UnixTimestamp): LocalTime;
|
|
30
32
|
static now(): LocalTime;
|
|
31
33
|
static fromComponents(c: {
|
|
32
34
|
year: number;
|
|
@@ -69,6 +71,7 @@ export declare class LocalTime {
|
|
|
69
71
|
*/
|
|
70
72
|
cmp(d: LocalTimeConfig): -1 | 0 | 1;
|
|
71
73
|
components(): LocalTimeComponents;
|
|
74
|
+
fromNow(now?: LocalTimeConfig): string;
|
|
72
75
|
getDate(): Date;
|
|
73
76
|
clone(): LocalTime;
|
|
74
77
|
unix(): UnixTimestamp;
|
|
@@ -84,6 +87,10 @@ export declare class LocalTime {
|
|
|
84
87
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
85
88
|
*/
|
|
86
89
|
toISODate(): IsoDate;
|
|
90
|
+
/**
|
|
91
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
92
|
+
*/
|
|
93
|
+
toISOTime(seconds?: boolean): string;
|
|
87
94
|
/**
|
|
88
95
|
* Returns e.g: `19840621_1705`
|
|
89
96
|
*/
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.localTime = exports.LocalTime = void 0;
|
|
4
4
|
const assert_1 = require("../error/assert");
|
|
5
|
+
const time_util_1 = require("../time/time.util");
|
|
5
6
|
const localDate_1 = require("./localDate");
|
|
6
7
|
/* eslint-disable no-dupe-class-members */
|
|
7
8
|
// Design choices:
|
|
@@ -17,8 +18,9 @@ const localDate_1 = require("./localDate");
|
|
|
17
18
|
* @experimental
|
|
18
19
|
*/
|
|
19
20
|
class LocalTime {
|
|
20
|
-
constructor($date) {
|
|
21
|
+
constructor($date, utcMode) {
|
|
21
22
|
this.$date = $date;
|
|
23
|
+
this.utcMode = utcMode;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* Parses input String into LocalDate.
|
|
@@ -31,6 +33,14 @@ class LocalTime {
|
|
|
31
33
|
}
|
|
32
34
|
return t;
|
|
33
35
|
}
|
|
36
|
+
utc() {
|
|
37
|
+
this.utcMode = true;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
local() {
|
|
41
|
+
this.utcMode = false;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
34
44
|
/**
|
|
35
45
|
* Returns null if invalid
|
|
36
46
|
*/
|
|
@@ -52,106 +62,110 @@ class LocalTime {
|
|
|
52
62
|
// throw new TypeError(`Cannot parse "${d}" into LocalTime`)
|
|
53
63
|
return null;
|
|
54
64
|
}
|
|
55
|
-
|
|
65
|
+
// if (utc) {
|
|
66
|
+
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
67
|
+
// }
|
|
68
|
+
return new LocalTime(date, false);
|
|
56
69
|
}
|
|
57
70
|
static isValid(d) {
|
|
58
71
|
return this.parseOrNull(d) !== null;
|
|
59
72
|
}
|
|
60
|
-
static unix(ts) {
|
|
61
|
-
return new LocalTime(new Date(ts * 1000));
|
|
62
|
-
}
|
|
63
73
|
static now() {
|
|
64
|
-
return
|
|
74
|
+
return new LocalTime(new Date(), false);
|
|
65
75
|
}
|
|
66
76
|
static fromComponents(c) {
|
|
67
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second));
|
|
77
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second), false);
|
|
68
78
|
}
|
|
69
79
|
get(unit) {
|
|
70
80
|
if (unit === 'year') {
|
|
71
|
-
return this.$date.getFullYear();
|
|
81
|
+
return this.utcMode ? this.$date.getUTCFullYear() : this.$date.getFullYear();
|
|
72
82
|
}
|
|
73
83
|
if (unit === 'month') {
|
|
74
|
-
return this.$date.getMonth() + 1;
|
|
84
|
+
return (this.utcMode ? this.$date.getUTCMonth() : this.$date.getMonth()) + 1;
|
|
75
85
|
}
|
|
76
86
|
if (unit === 'day') {
|
|
77
|
-
return this.$date.getDate();
|
|
87
|
+
return this.utcMode ? this.$date.getUTCDate() : this.$date.getDate();
|
|
78
88
|
}
|
|
79
89
|
if (unit === 'hour') {
|
|
80
|
-
return this.$date.getHours();
|
|
90
|
+
return this.utcMode ? this.$date.getUTCHours() : this.$date.getHours();
|
|
81
91
|
}
|
|
82
92
|
if (unit === 'minute') {
|
|
83
|
-
return this.$date.getMinutes();
|
|
93
|
+
return this.utcMode ? this.$date.getUTCMinutes() : this.$date.getMinutes();
|
|
84
94
|
}
|
|
85
95
|
// second
|
|
86
|
-
return this.$date.getSeconds();
|
|
96
|
+
return this.utcMode ? this.$date.getUTCSeconds() : this.$date.getSeconds();
|
|
87
97
|
}
|
|
88
98
|
set(unit, v, mutate = false) {
|
|
89
99
|
const t = mutate ? this : this.clone();
|
|
100
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
90
101
|
if (unit === 'year') {
|
|
91
|
-
t.$date.setFullYear(v);
|
|
102
|
+
this.utcMode ? t.$date.setUTCFullYear(v) : t.$date.setFullYear(v);
|
|
92
103
|
}
|
|
93
104
|
else if (unit === 'month') {
|
|
94
|
-
t.$date.setMonth(v - 1);
|
|
105
|
+
this.utcMode ? t.$date.setUTCMonth(v - 1) : t.$date.setMonth(v - 1);
|
|
95
106
|
}
|
|
96
107
|
else if (unit === 'day') {
|
|
97
|
-
t.$date.setDate(v);
|
|
108
|
+
this.utcMode ? t.$date.setUTCDate(v) : t.$date.setDate(v);
|
|
98
109
|
}
|
|
99
110
|
else if (unit === 'hour') {
|
|
100
|
-
t.$date.setHours(v);
|
|
111
|
+
this.utcMode ? t.$date.setUTCHours(v) : t.$date.setHours(v);
|
|
101
112
|
}
|
|
102
113
|
else if (unit === 'minute') {
|
|
103
|
-
t.$date.setMinutes(v);
|
|
114
|
+
this.utcMode ? t.$date.setUTCMinutes(v) : t.$date.setMinutes(v);
|
|
104
115
|
}
|
|
105
116
|
else if (unit === 'second') {
|
|
106
|
-
t.$date.setSeconds(v);
|
|
117
|
+
this.utcMode ? t.$date.setUTCSeconds(v) : t.$date.setSeconds(v);
|
|
107
118
|
}
|
|
119
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
108
120
|
return t;
|
|
109
121
|
}
|
|
110
122
|
year(v) {
|
|
111
|
-
return v === undefined ? this
|
|
123
|
+
return v === undefined ? this.get('year') : this.set('year', v);
|
|
112
124
|
}
|
|
113
125
|
month(v) {
|
|
114
|
-
return v === undefined ? this
|
|
126
|
+
return v === undefined ? this.get('month') : this.set('month', v);
|
|
115
127
|
}
|
|
116
128
|
date(v) {
|
|
117
|
-
return v === undefined ? this
|
|
129
|
+
return v === undefined ? this.get('day') : this.set('day', v);
|
|
118
130
|
}
|
|
119
131
|
hour(v) {
|
|
120
|
-
return v === undefined ? this
|
|
132
|
+
return v === undefined ? this.get('hour') : this.set('hour', v);
|
|
121
133
|
}
|
|
122
134
|
minute(v) {
|
|
123
|
-
return v === undefined ? this
|
|
135
|
+
return v === undefined ? this.get('minute') : this.set('minute', v);
|
|
124
136
|
}
|
|
125
137
|
second(v) {
|
|
126
|
-
return v === undefined ? this
|
|
138
|
+
return v === undefined ? this.get('second') : this.set('second', v);
|
|
127
139
|
}
|
|
128
140
|
setComponents(c, mutate = false) {
|
|
129
141
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
142
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
130
143
|
if (c.year) {
|
|
131
|
-
d.setFullYear(c.year);
|
|
144
|
+
this.utcMode ? d.setUTCFullYear(c.year) : d.setFullYear(c.year);
|
|
132
145
|
}
|
|
133
146
|
if (c.month) {
|
|
134
|
-
d.setMonth(c.month - 1);
|
|
147
|
+
this.utcMode ? d.setUTCMonth(c.month - 1) : d.setMonth(c.month - 1);
|
|
135
148
|
}
|
|
136
149
|
if (c.day) {
|
|
137
|
-
d.setDate(c.day);
|
|
150
|
+
this.utcMode ? d.setUTCDate(c.day) : d.setDate(c.day);
|
|
138
151
|
}
|
|
139
152
|
if (c.hour !== undefined) {
|
|
140
|
-
d.setHours(c.hour);
|
|
153
|
+
this.utcMode ? d.setUTCHours(c.hour) : d.setHours(c.hour);
|
|
141
154
|
}
|
|
142
155
|
if (c.minute !== undefined) {
|
|
143
|
-
d.setMinutes(c.minute);
|
|
156
|
+
this.utcMode ? d.setUTCMinutes(c.minute) : d.setMinutes(c.minute);
|
|
144
157
|
}
|
|
145
158
|
if (c.second !== undefined) {
|
|
146
|
-
d.setSeconds(c.second);
|
|
159
|
+
this.utcMode ? d.setUTCSeconds(c.second) : d.setSeconds(c.second);
|
|
147
160
|
}
|
|
148
|
-
|
|
161
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
162
|
+
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
149
163
|
}
|
|
150
164
|
add(num, unit, mutate = false) {
|
|
151
165
|
return this.set(unit, this.get(unit) + num, mutate);
|
|
152
166
|
}
|
|
153
167
|
subtract(num, unit, mutate = false) {
|
|
154
|
-
return this.add(-
|
|
168
|
+
return this.add(num * -1, unit, mutate);
|
|
155
169
|
}
|
|
156
170
|
absDiff(other, unit) {
|
|
157
171
|
return Math.abs(this.diff(other, unit));
|
|
@@ -189,40 +203,23 @@ class LocalTime {
|
|
|
189
203
|
startOf(unit, mutate = false) {
|
|
190
204
|
if (unit === 'second')
|
|
191
205
|
return this;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const c = this.components();
|
|
210
|
-
c.second = 0;
|
|
211
|
-
if (unit === 'year') {
|
|
212
|
-
c.month = c.day = 1;
|
|
213
|
-
c.hour = c.minute = 0;
|
|
214
|
-
}
|
|
215
|
-
else if (unit === 'month') {
|
|
216
|
-
c.day = 1;
|
|
217
|
-
c.hour = c.minute = 0;
|
|
218
|
-
}
|
|
219
|
-
else if (unit === 'day') {
|
|
220
|
-
c.hour = c.minute = 0;
|
|
221
|
-
}
|
|
222
|
-
else if (unit === 'hour') {
|
|
223
|
-
c.minute = 0;
|
|
224
|
-
}
|
|
225
|
-
return LocalTime.fromComponents(c);
|
|
206
|
+
const d = mutate ? this.$date : new Date(this.$date);
|
|
207
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
208
|
+
this.utcMode ? d.setUTCSeconds(0) : d.setSeconds(0);
|
|
209
|
+
if (unit !== 'minute') {
|
|
210
|
+
this.utcMode ? d.setUTCMinutes(0) : d.setMinutes(0);
|
|
211
|
+
if (unit !== 'hour') {
|
|
212
|
+
this.utcMode ? d.setUTCHours(0) : d.setHours(0);
|
|
213
|
+
if (unit !== 'day') {
|
|
214
|
+
this.utcMode ? d.setUTCDate(0) : d.setDate(0);
|
|
215
|
+
if (unit !== 'month') {
|
|
216
|
+
this.utcMode ? d.setUTCMonth(0) : d.setMonth(0);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
222
|
+
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
226
223
|
}
|
|
227
224
|
static sort(items, mutate = false, descending = false) {
|
|
228
225
|
const mod = descending ? -1 : 1;
|
|
@@ -277,6 +274,16 @@ class LocalTime {
|
|
|
277
274
|
}
|
|
278
275
|
// todo: endOf
|
|
279
276
|
components() {
|
|
277
|
+
if (this.utcMode) {
|
|
278
|
+
return {
|
|
279
|
+
year: this.$date.getUTCFullYear(),
|
|
280
|
+
month: this.$date.getUTCMonth() + 1,
|
|
281
|
+
day: this.$date.getUTCDate(),
|
|
282
|
+
hour: this.$date.getUTCHours(),
|
|
283
|
+
minute: this.$date.getUTCMinutes(),
|
|
284
|
+
second: this.$date.getSeconds(),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
280
287
|
return {
|
|
281
288
|
year: this.$date.getFullYear(),
|
|
282
289
|
month: this.$date.getMonth() + 1,
|
|
@@ -286,11 +293,20 @@ class LocalTime {
|
|
|
286
293
|
second: this.$date.getSeconds(),
|
|
287
294
|
};
|
|
288
295
|
}
|
|
296
|
+
fromNow(now = LocalTime.now()) {
|
|
297
|
+
const msDiff = LocalTime.of(now).unixMillis() - this.unixMillis();
|
|
298
|
+
if (msDiff === 0)
|
|
299
|
+
return 'now';
|
|
300
|
+
if (msDiff >= 0) {
|
|
301
|
+
return `${(0, time_util_1._ms)(msDiff)} ago`;
|
|
302
|
+
}
|
|
303
|
+
return `in ${(0, time_util_1._ms)(msDiff * -1)}`;
|
|
304
|
+
}
|
|
289
305
|
getDate() {
|
|
290
306
|
return this.$date;
|
|
291
307
|
}
|
|
292
308
|
clone() {
|
|
293
|
-
return new LocalTime(new Date(this.$date));
|
|
309
|
+
return new LocalTime(new Date(this.$date), this.utcMode);
|
|
294
310
|
}
|
|
295
311
|
unix() {
|
|
296
312
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
@@ -302,14 +318,31 @@ class LocalTime {
|
|
|
302
318
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
303
319
|
}
|
|
304
320
|
toLocalDate() {
|
|
321
|
+
if (this.utcMode) {
|
|
322
|
+
return localDate_1.LocalDate.create(this.$date.getUTCFullYear(), this.$date.getUTCMonth() + 1, this.$date.getUTCDate());
|
|
323
|
+
}
|
|
305
324
|
return localDate_1.LocalDate.create(this.$date.getFullYear(), this.$date.getMonth() + 1, this.$date.getDate());
|
|
306
325
|
}
|
|
307
326
|
toPretty(seconds = true) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
.
|
|
311
|
-
.
|
|
312
|
-
.
|
|
327
|
+
const { year, month, day, hour, minute, second } = this.components();
|
|
328
|
+
return ([
|
|
329
|
+
String(year).padStart(4, '0'),
|
|
330
|
+
String(month).padStart(2, '0'),
|
|
331
|
+
String(day).padStart(2, '0'),
|
|
332
|
+
].join('-') +
|
|
333
|
+
' ' +
|
|
334
|
+
[
|
|
335
|
+
String(hour).padStart(2, '0'),
|
|
336
|
+
String(minute).padStart(2, '0'),
|
|
337
|
+
seconds && String(second).padStart(2, '0'),
|
|
338
|
+
]
|
|
339
|
+
.filter(Boolean)
|
|
340
|
+
.join(':'));
|
|
341
|
+
// return this.$date
|
|
342
|
+
// .toISOString()
|
|
343
|
+
// .slice(0, seconds ? 19 : 16)
|
|
344
|
+
// .split('T')
|
|
345
|
+
// .join(' ')
|
|
313
346
|
}
|
|
314
347
|
/**
|
|
315
348
|
* Returns e.g: `1984-06-21T17:56:21`, only the date part of DateTime
|
|
@@ -321,20 +354,41 @@ class LocalTime {
|
|
|
321
354
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
322
355
|
*/
|
|
323
356
|
toISODate() {
|
|
324
|
-
|
|
357
|
+
const { year, month, day } = this.components();
|
|
358
|
+
return [
|
|
359
|
+
String(year).padStart(4, '0'),
|
|
360
|
+
String(month).padStart(2, '0'),
|
|
361
|
+
String(day).padStart(2, '0'),
|
|
362
|
+
].join('-');
|
|
363
|
+
// return this.$date.toISOString().slice(0, 10)
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
367
|
+
*/
|
|
368
|
+
toISOTime(seconds = true) {
|
|
369
|
+
// return this.$date.toISOString().slice(11, seconds ? 19 : 16)
|
|
370
|
+
const { hour, minute, second } = this.components();
|
|
371
|
+
return [
|
|
372
|
+
String(hour).padStart(2, '0'),
|
|
373
|
+
String(minute).padStart(2, '0'),
|
|
374
|
+
seconds && String(second).padStart(2, '0'),
|
|
375
|
+
]
|
|
376
|
+
.filter(Boolean)
|
|
377
|
+
.join(':');
|
|
325
378
|
}
|
|
326
379
|
/**
|
|
327
380
|
* Returns e.g: `19840621_1705`
|
|
328
381
|
*/
|
|
329
382
|
toStringCompact(seconds = false) {
|
|
383
|
+
const { year, month, day, hour, minute, second } = this.components();
|
|
330
384
|
return [
|
|
331
|
-
String(
|
|
332
|
-
String(
|
|
333
|
-
String(
|
|
385
|
+
String(year).padStart(4, '0'),
|
|
386
|
+
String(month).padStart(2, '0'),
|
|
387
|
+
String(day).padStart(2, '0'),
|
|
334
388
|
'_',
|
|
335
|
-
String(
|
|
336
|
-
String(
|
|
337
|
-
seconds ? String(
|
|
389
|
+
String(hour).padStart(2, '0'),
|
|
390
|
+
String(minute).padStart(2, '0'),
|
|
391
|
+
seconds ? String(second).padStart(2, '0') : '',
|
|
338
392
|
].join('');
|
|
339
393
|
}
|
|
340
394
|
toString() {
|
|
@@ -36,6 +36,9 @@ export class LocalDate {
|
|
|
36
36
|
static fromDate(d) {
|
|
37
37
|
return new LocalDate(d.getFullYear(), d.getMonth() + 1, d.getDate());
|
|
38
38
|
}
|
|
39
|
+
static fromDateUTC(d) {
|
|
40
|
+
return new LocalDate(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate());
|
|
41
|
+
}
|
|
39
42
|
/**
|
|
40
43
|
* Returns null if invalid.
|
|
41
44
|
*/
|
|
@@ -61,6 +64,9 @@ export class LocalDate {
|
|
|
61
64
|
static today() {
|
|
62
65
|
return this.fromDate(new Date());
|
|
63
66
|
}
|
|
67
|
+
static todayUTC() {
|
|
68
|
+
return this.fromDateUTC(new Date());
|
|
69
|
+
}
|
|
64
70
|
static sort(items, mutate = false, descending = false) {
|
|
65
71
|
const mod = descending ? -1 : 1;
|
|
66
72
|
return (mutate ? items : [...items]).sort((a, b) => a.cmp(b) * mod);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _assert } from '../error/assert';
|
|
2
|
+
import { _ms } from '../time/time.util';
|
|
2
3
|
import { LocalDate } from './localDate';
|
|
3
4
|
/* eslint-disable no-dupe-class-members */
|
|
4
5
|
// Design choices:
|
|
@@ -14,8 +15,9 @@ import { LocalDate } from './localDate';
|
|
|
14
15
|
* @experimental
|
|
15
16
|
*/
|
|
16
17
|
export class LocalTime {
|
|
17
|
-
constructor($date) {
|
|
18
|
+
constructor($date, utcMode) {
|
|
18
19
|
this.$date = $date;
|
|
20
|
+
this.utcMode = utcMode;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Parses input String into LocalDate.
|
|
@@ -28,6 +30,14 @@ export class LocalTime {
|
|
|
28
30
|
}
|
|
29
31
|
return t;
|
|
30
32
|
}
|
|
33
|
+
utc() {
|
|
34
|
+
this.utcMode = true;
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
local() {
|
|
38
|
+
this.utcMode = false;
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
31
41
|
/**
|
|
32
42
|
* Returns null if invalid
|
|
33
43
|
*/
|
|
@@ -49,106 +59,110 @@ export class LocalTime {
|
|
|
49
59
|
// throw new TypeError(`Cannot parse "${d}" into LocalTime`)
|
|
50
60
|
return null;
|
|
51
61
|
}
|
|
52
|
-
|
|
62
|
+
// if (utc) {
|
|
63
|
+
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
64
|
+
// }
|
|
65
|
+
return new LocalTime(date, false);
|
|
53
66
|
}
|
|
54
67
|
static isValid(d) {
|
|
55
68
|
return this.parseOrNull(d) !== null;
|
|
56
69
|
}
|
|
57
|
-
static unix(ts) {
|
|
58
|
-
return new LocalTime(new Date(ts * 1000));
|
|
59
|
-
}
|
|
60
70
|
static now() {
|
|
61
|
-
return
|
|
71
|
+
return new LocalTime(new Date(), false);
|
|
62
72
|
}
|
|
63
73
|
static fromComponents(c) {
|
|
64
|
-
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);
|
|
65
75
|
}
|
|
66
76
|
get(unit) {
|
|
67
77
|
if (unit === 'year') {
|
|
68
|
-
return this.$date.getFullYear();
|
|
78
|
+
return this.utcMode ? this.$date.getUTCFullYear() : this.$date.getFullYear();
|
|
69
79
|
}
|
|
70
80
|
if (unit === 'month') {
|
|
71
|
-
return this.$date.getMonth() + 1;
|
|
81
|
+
return (this.utcMode ? this.$date.getUTCMonth() : this.$date.getMonth()) + 1;
|
|
72
82
|
}
|
|
73
83
|
if (unit === 'day') {
|
|
74
|
-
return this.$date.getDate();
|
|
84
|
+
return this.utcMode ? this.$date.getUTCDate() : this.$date.getDate();
|
|
75
85
|
}
|
|
76
86
|
if (unit === 'hour') {
|
|
77
|
-
return this.$date.getHours();
|
|
87
|
+
return this.utcMode ? this.$date.getUTCHours() : this.$date.getHours();
|
|
78
88
|
}
|
|
79
89
|
if (unit === 'minute') {
|
|
80
|
-
return this.$date.getMinutes();
|
|
90
|
+
return this.utcMode ? this.$date.getUTCMinutes() : this.$date.getMinutes();
|
|
81
91
|
}
|
|
82
92
|
// second
|
|
83
|
-
return this.$date.getSeconds();
|
|
93
|
+
return this.utcMode ? this.$date.getUTCSeconds() : this.$date.getSeconds();
|
|
84
94
|
}
|
|
85
95
|
set(unit, v, mutate = false) {
|
|
86
96
|
const t = mutate ? this : this.clone();
|
|
97
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
87
98
|
if (unit === 'year') {
|
|
88
|
-
t.$date.setFullYear(v);
|
|
99
|
+
this.utcMode ? t.$date.setUTCFullYear(v) : t.$date.setFullYear(v);
|
|
89
100
|
}
|
|
90
101
|
else if (unit === 'month') {
|
|
91
|
-
t.$date.setMonth(v - 1);
|
|
102
|
+
this.utcMode ? t.$date.setUTCMonth(v - 1) : t.$date.setMonth(v - 1);
|
|
92
103
|
}
|
|
93
104
|
else if (unit === 'day') {
|
|
94
|
-
t.$date.setDate(v);
|
|
105
|
+
this.utcMode ? t.$date.setUTCDate(v) : t.$date.setDate(v);
|
|
95
106
|
}
|
|
96
107
|
else if (unit === 'hour') {
|
|
97
|
-
t.$date.setHours(v);
|
|
108
|
+
this.utcMode ? t.$date.setUTCHours(v) : t.$date.setHours(v);
|
|
98
109
|
}
|
|
99
110
|
else if (unit === 'minute') {
|
|
100
|
-
t.$date.setMinutes(v);
|
|
111
|
+
this.utcMode ? t.$date.setUTCMinutes(v) : t.$date.setMinutes(v);
|
|
101
112
|
}
|
|
102
113
|
else if (unit === 'second') {
|
|
103
|
-
t.$date.setSeconds(v);
|
|
114
|
+
this.utcMode ? t.$date.setUTCSeconds(v) : t.$date.setSeconds(v);
|
|
104
115
|
}
|
|
116
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
105
117
|
return t;
|
|
106
118
|
}
|
|
107
119
|
year(v) {
|
|
108
|
-
return v === undefined ? this
|
|
120
|
+
return v === undefined ? this.get('year') : this.set('year', v);
|
|
109
121
|
}
|
|
110
122
|
month(v) {
|
|
111
|
-
return v === undefined ? this
|
|
123
|
+
return v === undefined ? this.get('month') : this.set('month', v);
|
|
112
124
|
}
|
|
113
125
|
date(v) {
|
|
114
|
-
return v === undefined ? this
|
|
126
|
+
return v === undefined ? this.get('day') : this.set('day', v);
|
|
115
127
|
}
|
|
116
128
|
hour(v) {
|
|
117
|
-
return v === undefined ? this
|
|
129
|
+
return v === undefined ? this.get('hour') : this.set('hour', v);
|
|
118
130
|
}
|
|
119
131
|
minute(v) {
|
|
120
|
-
return v === undefined ? this
|
|
132
|
+
return v === undefined ? this.get('minute') : this.set('minute', v);
|
|
121
133
|
}
|
|
122
134
|
second(v) {
|
|
123
|
-
return v === undefined ? this
|
|
135
|
+
return v === undefined ? this.get('second') : this.set('second', v);
|
|
124
136
|
}
|
|
125
137
|
setComponents(c, mutate = false) {
|
|
126
138
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
139
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
127
140
|
if (c.year) {
|
|
128
|
-
d.setFullYear(c.year);
|
|
141
|
+
this.utcMode ? d.setUTCFullYear(c.year) : d.setFullYear(c.year);
|
|
129
142
|
}
|
|
130
143
|
if (c.month) {
|
|
131
|
-
d.setMonth(c.month - 1);
|
|
144
|
+
this.utcMode ? d.setUTCMonth(c.month - 1) : d.setMonth(c.month - 1);
|
|
132
145
|
}
|
|
133
146
|
if (c.day) {
|
|
134
|
-
d.setDate(c.day);
|
|
147
|
+
this.utcMode ? d.setUTCDate(c.day) : d.setDate(c.day);
|
|
135
148
|
}
|
|
136
149
|
if (c.hour !== undefined) {
|
|
137
|
-
d.setHours(c.hour);
|
|
150
|
+
this.utcMode ? d.setUTCHours(c.hour) : d.setHours(c.hour);
|
|
138
151
|
}
|
|
139
152
|
if (c.minute !== undefined) {
|
|
140
|
-
d.setMinutes(c.minute);
|
|
153
|
+
this.utcMode ? d.setUTCMinutes(c.minute) : d.setMinutes(c.minute);
|
|
141
154
|
}
|
|
142
155
|
if (c.second !== undefined) {
|
|
143
|
-
d.setSeconds(c.second);
|
|
156
|
+
this.utcMode ? d.setUTCSeconds(c.second) : d.setSeconds(c.second);
|
|
144
157
|
}
|
|
145
|
-
|
|
158
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
159
|
+
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
146
160
|
}
|
|
147
161
|
add(num, unit, mutate = false) {
|
|
148
162
|
return this.set(unit, this.get(unit) + num, mutate);
|
|
149
163
|
}
|
|
150
164
|
subtract(num, unit, mutate = false) {
|
|
151
|
-
return this.add(-
|
|
165
|
+
return this.add(num * -1, unit, mutate);
|
|
152
166
|
}
|
|
153
167
|
absDiff(other, unit) {
|
|
154
168
|
return Math.abs(this.diff(other, unit));
|
|
@@ -186,40 +200,23 @@ export class LocalTime {
|
|
|
186
200
|
startOf(unit, mutate = false) {
|
|
187
201
|
if (unit === 'second')
|
|
188
202
|
return this;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const c = this.components();
|
|
207
|
-
c.second = 0;
|
|
208
|
-
if (unit === 'year') {
|
|
209
|
-
c.month = c.day = 1;
|
|
210
|
-
c.hour = c.minute = 0;
|
|
211
|
-
}
|
|
212
|
-
else if (unit === 'month') {
|
|
213
|
-
c.day = 1;
|
|
214
|
-
c.hour = c.minute = 0;
|
|
215
|
-
}
|
|
216
|
-
else if (unit === 'day') {
|
|
217
|
-
c.hour = c.minute = 0;
|
|
218
|
-
}
|
|
219
|
-
else if (unit === 'hour') {
|
|
220
|
-
c.minute = 0;
|
|
221
|
-
}
|
|
222
|
-
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);
|
|
223
220
|
}
|
|
224
221
|
static sort(items, mutate = false, descending = false) {
|
|
225
222
|
const mod = descending ? -1 : 1;
|
|
@@ -274,6 +271,16 @@ export class LocalTime {
|
|
|
274
271
|
}
|
|
275
272
|
// todo: endOf
|
|
276
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
|
+
}
|
|
277
284
|
return {
|
|
278
285
|
year: this.$date.getFullYear(),
|
|
279
286
|
month: this.$date.getMonth() + 1,
|
|
@@ -283,11 +290,20 @@ export class LocalTime {
|
|
|
283
290
|
second: this.$date.getSeconds(),
|
|
284
291
|
};
|
|
285
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
|
+
}
|
|
286
302
|
getDate() {
|
|
287
303
|
return this.$date;
|
|
288
304
|
}
|
|
289
305
|
clone() {
|
|
290
|
-
return new LocalTime(new Date(this.$date));
|
|
306
|
+
return new LocalTime(new Date(this.$date), this.utcMode);
|
|
291
307
|
}
|
|
292
308
|
unix() {
|
|
293
309
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
@@ -299,14 +315,31 @@ export class LocalTime {
|
|
|
299
315
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
300
316
|
}
|
|
301
317
|
toLocalDate() {
|
|
318
|
+
if (this.utcMode) {
|
|
319
|
+
return LocalDate.create(this.$date.getUTCFullYear(), this.$date.getUTCMonth() + 1, this.$date.getUTCDate());
|
|
320
|
+
}
|
|
302
321
|
return LocalDate.create(this.$date.getFullYear(), this.$date.getMonth() + 1, this.$date.getDate());
|
|
303
322
|
}
|
|
304
323
|
toPretty(seconds = true) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
.
|
|
308
|
-
.
|
|
309
|
-
.
|
|
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(' ')
|
|
310
343
|
}
|
|
311
344
|
/**
|
|
312
345
|
* Returns e.g: `1984-06-21T17:56:21`, only the date part of DateTime
|
|
@@ -318,20 +351,41 @@ export class LocalTime {
|
|
|
318
351
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
319
352
|
*/
|
|
320
353
|
toISODate() {
|
|
321
|
-
|
|
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(':');
|
|
322
375
|
}
|
|
323
376
|
/**
|
|
324
377
|
* Returns e.g: `19840621_1705`
|
|
325
378
|
*/
|
|
326
379
|
toStringCompact(seconds = false) {
|
|
380
|
+
const { year, month, day, hour, minute, second } = this.components();
|
|
327
381
|
return [
|
|
328
|
-
String(
|
|
329
|
-
String(
|
|
330
|
-
String(
|
|
382
|
+
String(year).padStart(4, '0'),
|
|
383
|
+
String(month).padStart(2, '0'),
|
|
384
|
+
String(day).padStart(2, '0'),
|
|
331
385
|
'_',
|
|
332
|
-
String(
|
|
333
|
-
String(
|
|
334
|
-
seconds ? String(
|
|
386
|
+
String(hour).padStart(2, '0'),
|
|
387
|
+
String(minute).padStart(2, '0'),
|
|
388
|
+
seconds ? String(second).padStart(2, '0') : '',
|
|
335
389
|
].join('');
|
|
336
390
|
}
|
|
337
391
|
toString() {
|
package/package.json
CHANGED
|
@@ -47,6 +47,10 @@ export class LocalDate {
|
|
|
47
47
|
return new LocalDate(d.getFullYear(), d.getMonth() + 1, d.getDate())
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
static fromDateUTC(d: Date): LocalDate {
|
|
51
|
+
return new LocalDate(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate())
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
/**
|
|
51
55
|
* Returns null if invalid.
|
|
52
56
|
*/
|
|
@@ -79,6 +83,10 @@ export class LocalDate {
|
|
|
79
83
|
return this.fromDate(new Date())
|
|
80
84
|
}
|
|
81
85
|
|
|
86
|
+
static todayUTC(): LocalDate {
|
|
87
|
+
return this.fromDateUTC(new Date())
|
|
88
|
+
}
|
|
89
|
+
|
|
82
90
|
static sort(items: LocalDate[], mutate = false, descending = false): LocalDate[] {
|
|
83
91
|
const mod = descending ? -1 : 1
|
|
84
92
|
return (mutate ? items : [...items]).sort((a, b) => a.cmp(b) * mod)
|
|
@@ -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
|
|
|
@@ -30,7 +31,7 @@ export interface LocalTimeComponents {
|
|
|
30
31
|
* @experimental
|
|
31
32
|
*/
|
|
32
33
|
export class LocalTime {
|
|
33
|
-
private constructor(private $date: Date) {}
|
|
34
|
+
private constructor(private $date: Date, public utcMode: boolean) {}
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* Parses input String into LocalDate.
|
|
@@ -46,6 +47,16 @@ export class LocalTime {
|
|
|
46
47
|
return t
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
utc(): this {
|
|
51
|
+
this.utcMode = true
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
local(): this {
|
|
56
|
+
this.utcMode = false
|
|
57
|
+
return this
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
/**
|
|
50
61
|
* Returns null if invalid
|
|
51
62
|
*/
|
|
@@ -68,63 +79,65 @@ export class LocalTime {
|
|
|
68
79
|
return null
|
|
69
80
|
}
|
|
70
81
|
|
|
71
|
-
|
|
82
|
+
// if (utc) {
|
|
83
|
+
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
84
|
+
// }
|
|
85
|
+
|
|
86
|
+
return new LocalTime(date, false)
|
|
72
87
|
}
|
|
73
88
|
|
|
74
89
|
static isValid(d: LocalTimeConfig): boolean {
|
|
75
90
|
return this.parseOrNull(d) !== null
|
|
76
91
|
}
|
|
77
92
|
|
|
78
|
-
static unix(ts: UnixTimestamp): LocalTime {
|
|
79
|
-
return new LocalTime(new Date(ts * 1000))
|
|
80
|
-
}
|
|
81
|
-
|
|
82
93
|
static now(): LocalTime {
|
|
83
|
-
return
|
|
94
|
+
return new LocalTime(new Date(), false)
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
static fromComponents(
|
|
87
98
|
c: { year: number; month: number } & Partial<LocalTimeComponents>,
|
|
88
99
|
): LocalTime {
|
|
89
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second))
|
|
100
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second), false)
|
|
90
101
|
}
|
|
91
102
|
|
|
92
103
|
get(unit: LocalTimeUnit): number {
|
|
93
104
|
if (unit === 'year') {
|
|
94
|
-
return this.$date.getFullYear()
|
|
105
|
+
return this.utcMode ? this.$date.getUTCFullYear() : this.$date.getFullYear()
|
|
95
106
|
}
|
|
96
107
|
if (unit === 'month') {
|
|
97
|
-
return this.$date.getMonth() + 1
|
|
108
|
+
return (this.utcMode ? this.$date.getUTCMonth() : this.$date.getMonth()) + 1
|
|
98
109
|
}
|
|
99
110
|
if (unit === 'day') {
|
|
100
|
-
return this.$date.getDate()
|
|
111
|
+
return this.utcMode ? this.$date.getUTCDate() : this.$date.getDate()
|
|
101
112
|
}
|
|
102
113
|
if (unit === 'hour') {
|
|
103
|
-
return this.$date.getHours()
|
|
114
|
+
return this.utcMode ? this.$date.getUTCHours() : this.$date.getHours()
|
|
104
115
|
}
|
|
105
116
|
if (unit === 'minute') {
|
|
106
|
-
return this.$date.getMinutes()
|
|
117
|
+
return this.utcMode ? this.$date.getUTCMinutes() : this.$date.getMinutes()
|
|
107
118
|
}
|
|
108
119
|
// second
|
|
109
|
-
return this.$date.getSeconds()
|
|
120
|
+
return this.utcMode ? this.$date.getUTCSeconds() : this.$date.getSeconds()
|
|
110
121
|
}
|
|
111
122
|
|
|
112
123
|
set(unit: LocalTimeUnit, v: number, mutate = false): LocalTime {
|
|
113
124
|
const t = mutate ? this : this.clone()
|
|
114
125
|
|
|
126
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
115
127
|
if (unit === 'year') {
|
|
116
|
-
t.$date.setFullYear(v)
|
|
128
|
+
this.utcMode ? t.$date.setUTCFullYear(v) : t.$date.setFullYear(v)
|
|
117
129
|
} else if (unit === 'month') {
|
|
118
|
-
t.$date.setMonth(v - 1)
|
|
130
|
+
this.utcMode ? t.$date.setUTCMonth(v - 1) : t.$date.setMonth(v - 1)
|
|
119
131
|
} else if (unit === 'day') {
|
|
120
|
-
t.$date.setDate(v)
|
|
132
|
+
this.utcMode ? t.$date.setUTCDate(v) : t.$date.setDate(v)
|
|
121
133
|
} else if (unit === 'hour') {
|
|
122
|
-
t.$date.setHours(v)
|
|
134
|
+
this.utcMode ? t.$date.setUTCHours(v) : t.$date.setHours(v)
|
|
123
135
|
} else if (unit === 'minute') {
|
|
124
|
-
t.$date.setMinutes(v)
|
|
136
|
+
this.utcMode ? t.$date.setUTCMinutes(v) : t.$date.setMinutes(v)
|
|
125
137
|
} else if (unit === 'second') {
|
|
126
|
-
t.$date.setSeconds(v)
|
|
138
|
+
this.utcMode ? t.$date.setUTCSeconds(v) : t.$date.setSeconds(v)
|
|
127
139
|
}
|
|
140
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
128
141
|
|
|
129
142
|
return t
|
|
130
143
|
}
|
|
@@ -132,57 +145,59 @@ export class LocalTime {
|
|
|
132
145
|
year(): number
|
|
133
146
|
year(v: number): LocalTime
|
|
134
147
|
year(v?: number): number | LocalTime {
|
|
135
|
-
return v === undefined ? this
|
|
148
|
+
return v === undefined ? this.get('year') : this.set('year', v)
|
|
136
149
|
}
|
|
137
150
|
month(): number
|
|
138
151
|
month(v: number): LocalTime
|
|
139
152
|
month(v?: number): number | LocalTime {
|
|
140
|
-
return v === undefined ? this
|
|
153
|
+
return v === undefined ? this.get('month') : this.set('month', v)
|
|
141
154
|
}
|
|
142
155
|
date(): number
|
|
143
156
|
date(v: number): LocalTime
|
|
144
157
|
date(v?: number): number | LocalTime {
|
|
145
|
-
return v === undefined ? this
|
|
158
|
+
return v === undefined ? this.get('day') : this.set('day', v)
|
|
146
159
|
}
|
|
147
160
|
hour(): number
|
|
148
161
|
hour(v: number): LocalTime
|
|
149
162
|
hour(v?: number): number | LocalTime {
|
|
150
|
-
return v === undefined ? this
|
|
163
|
+
return v === undefined ? this.get('hour') : this.set('hour', v)
|
|
151
164
|
}
|
|
152
165
|
minute(): number
|
|
153
166
|
minute(v: number): LocalTime
|
|
154
167
|
minute(v?: number): number | LocalTime {
|
|
155
|
-
return v === undefined ? this
|
|
168
|
+
return v === undefined ? this.get('minute') : this.set('minute', v)
|
|
156
169
|
}
|
|
157
170
|
second(): number
|
|
158
171
|
second(v: number): LocalTime
|
|
159
172
|
second(v?: number): number | LocalTime {
|
|
160
|
-
return v === undefined ? this
|
|
173
|
+
return v === undefined ? this.get('second') : this.set('second', v)
|
|
161
174
|
}
|
|
162
175
|
|
|
163
176
|
setComponents(c: Partial<LocalTimeComponents>, mutate = false): LocalTime {
|
|
164
177
|
const d = mutate ? this.$date : new Date(this.$date)
|
|
165
178
|
|
|
179
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
166
180
|
if (c.year) {
|
|
167
|
-
d.setFullYear(c.year)
|
|
181
|
+
this.utcMode ? d.setUTCFullYear(c.year) : d.setFullYear(c.year)
|
|
168
182
|
}
|
|
169
183
|
if (c.month) {
|
|
170
|
-
d.setMonth(c.month - 1)
|
|
184
|
+
this.utcMode ? d.setUTCMonth(c.month - 1) : d.setMonth(c.month - 1)
|
|
171
185
|
}
|
|
172
186
|
if (c.day) {
|
|
173
|
-
d.setDate(c.day)
|
|
187
|
+
this.utcMode ? d.setUTCDate(c.day) : d.setDate(c.day)
|
|
174
188
|
}
|
|
175
189
|
if (c.hour !== undefined) {
|
|
176
|
-
d.setHours(c.hour)
|
|
190
|
+
this.utcMode ? d.setUTCHours(c.hour) : d.setHours(c.hour)
|
|
177
191
|
}
|
|
178
192
|
if (c.minute !== undefined) {
|
|
179
|
-
d.setMinutes(c.minute)
|
|
193
|
+
this.utcMode ? d.setUTCMinutes(c.minute) : d.setMinutes(c.minute)
|
|
180
194
|
}
|
|
181
195
|
if (c.second !== undefined) {
|
|
182
|
-
d.setSeconds(c.second)
|
|
196
|
+
this.utcMode ? d.setUTCSeconds(c.second) : d.setSeconds(c.second)
|
|
183
197
|
}
|
|
198
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
184
199
|
|
|
185
|
-
return mutate ? this : new LocalTime(d)
|
|
200
|
+
return mutate ? this : new LocalTime(d, this.utcMode)
|
|
186
201
|
}
|
|
187
202
|
|
|
188
203
|
add(num: number, unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
@@ -190,7 +205,7 @@ export class LocalTime {
|
|
|
190
205
|
}
|
|
191
206
|
|
|
192
207
|
subtract(num: number, unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
193
|
-
return this.add(-
|
|
208
|
+
return this.add(num * -1, unit, mutate)
|
|
194
209
|
}
|
|
195
210
|
|
|
196
211
|
absDiff(other: LocalTimeConfig, unit: LocalTimeUnit): number {
|
|
@@ -233,36 +248,25 @@ export class LocalTime {
|
|
|
233
248
|
startOf(unit: LocalTimeUnit, mutate = false): LocalTime {
|
|
234
249
|
if (unit === 'second') return this
|
|
235
250
|
|
|
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()
|
|
251
|
+
const d = mutate ? this.$date : new Date(this.$date)
|
|
251
252
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
253
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
254
|
+
this.utcMode ? d.setUTCSeconds(0) : d.setSeconds(0)
|
|
255
|
+
if (unit !== 'minute') {
|
|
256
|
+
this.utcMode ? d.setUTCMinutes(0) : d.setMinutes(0)
|
|
257
|
+
if (unit !== 'hour') {
|
|
258
|
+
this.utcMode ? d.setUTCHours(0) : d.setHours(0)
|
|
259
|
+
if (unit !== 'day') {
|
|
260
|
+
this.utcMode ? d.setUTCDate(0) : d.setDate(0)
|
|
261
|
+
if (unit !== 'month') {
|
|
262
|
+
this.utcMode ? d.setUTCMonth(0) : d.setMonth(0)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
263
266
|
}
|
|
267
|
+
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
264
268
|
|
|
265
|
-
return LocalTime.
|
|
269
|
+
return mutate ? this : new LocalTime(d, this.utcMode)
|
|
266
270
|
}
|
|
267
271
|
|
|
268
272
|
static sort(items: LocalTime[], mutate = false, descending = false): LocalTime[] {
|
|
@@ -330,6 +334,17 @@ export class LocalTime {
|
|
|
330
334
|
// todo: endOf
|
|
331
335
|
|
|
332
336
|
components(): LocalTimeComponents {
|
|
337
|
+
if (this.utcMode) {
|
|
338
|
+
return {
|
|
339
|
+
year: this.$date.getUTCFullYear(),
|
|
340
|
+
month: this.$date.getUTCMonth() + 1,
|
|
341
|
+
day: this.$date.getUTCDate(),
|
|
342
|
+
hour: this.$date.getUTCHours(),
|
|
343
|
+
minute: this.$date.getUTCMinutes(),
|
|
344
|
+
second: this.$date.getSeconds(),
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
333
348
|
return {
|
|
334
349
|
year: this.$date.getFullYear(),
|
|
335
350
|
month: this.$date.getMonth() + 1,
|
|
@@ -340,12 +355,24 @@ export class LocalTime {
|
|
|
340
355
|
}
|
|
341
356
|
}
|
|
342
357
|
|
|
358
|
+
fromNow(now: LocalTimeConfig = LocalTime.now()): string {
|
|
359
|
+
const msDiff = LocalTime.of(now).unixMillis() - this.unixMillis()
|
|
360
|
+
|
|
361
|
+
if (msDiff === 0) return 'now'
|
|
362
|
+
|
|
363
|
+
if (msDiff >= 0) {
|
|
364
|
+
return `${_ms(msDiff)} ago`
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return `in ${_ms(msDiff * -1)}`
|
|
368
|
+
}
|
|
369
|
+
|
|
343
370
|
getDate(): Date {
|
|
344
371
|
return this.$date
|
|
345
372
|
}
|
|
346
373
|
|
|
347
374
|
clone(): LocalTime {
|
|
348
|
-
return new LocalTime(new Date(this.$date))
|
|
375
|
+
return new LocalTime(new Date(this.$date), this.utcMode)
|
|
349
376
|
}
|
|
350
377
|
|
|
351
378
|
unix(): UnixTimestamp {
|
|
@@ -361,6 +388,14 @@ export class LocalTime {
|
|
|
361
388
|
}
|
|
362
389
|
|
|
363
390
|
toLocalDate(): LocalDate {
|
|
391
|
+
if (this.utcMode) {
|
|
392
|
+
return LocalDate.create(
|
|
393
|
+
this.$date.getUTCFullYear(),
|
|
394
|
+
this.$date.getUTCMonth() + 1,
|
|
395
|
+
this.$date.getUTCDate(),
|
|
396
|
+
)
|
|
397
|
+
}
|
|
398
|
+
|
|
364
399
|
return LocalDate.create(
|
|
365
400
|
this.$date.getFullYear(),
|
|
366
401
|
this.$date.getMonth() + 1,
|
|
@@ -369,11 +404,29 @@ export class LocalTime {
|
|
|
369
404
|
}
|
|
370
405
|
|
|
371
406
|
toPretty(seconds = true): IsoDateTime {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
407
|
+
const { year, month, day, hour, minute, second } = this.components()
|
|
408
|
+
|
|
409
|
+
return (
|
|
410
|
+
[
|
|
411
|
+
String(year).padStart(4, '0'),
|
|
412
|
+
String(month).padStart(2, '0'),
|
|
413
|
+
String(day).padStart(2, '0'),
|
|
414
|
+
].join('-') +
|
|
415
|
+
' ' +
|
|
416
|
+
[
|
|
417
|
+
String(hour).padStart(2, '0'),
|
|
418
|
+
String(minute).padStart(2, '0'),
|
|
419
|
+
seconds && String(second).padStart(2, '0'),
|
|
420
|
+
]
|
|
421
|
+
.filter(Boolean)
|
|
422
|
+
.join(':')
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
// return this.$date
|
|
426
|
+
// .toISOString()
|
|
427
|
+
// .slice(0, seconds ? 19 : 16)
|
|
428
|
+
// .split('T')
|
|
429
|
+
// .join(' ')
|
|
377
430
|
}
|
|
378
431
|
|
|
379
432
|
/**
|
|
@@ -387,21 +440,47 @@ export class LocalTime {
|
|
|
387
440
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
388
441
|
*/
|
|
389
442
|
toISODate(): IsoDate {
|
|
390
|
-
|
|
443
|
+
const { year, month, day } = this.components()
|
|
444
|
+
|
|
445
|
+
return [
|
|
446
|
+
String(year).padStart(4, '0'),
|
|
447
|
+
String(month).padStart(2, '0'),
|
|
448
|
+
String(day).padStart(2, '0'),
|
|
449
|
+
].join('-')
|
|
450
|
+
|
|
451
|
+
// return this.$date.toISOString().slice(0, 10)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
456
|
+
*/
|
|
457
|
+
toISOTime(seconds = true): string {
|
|
458
|
+
// return this.$date.toISOString().slice(11, seconds ? 19 : 16)
|
|
459
|
+
const { hour, minute, second } = this.components()
|
|
460
|
+
|
|
461
|
+
return [
|
|
462
|
+
String(hour).padStart(2, '0'),
|
|
463
|
+
String(minute).padStart(2, '0'),
|
|
464
|
+
seconds && String(second).padStart(2, '0'),
|
|
465
|
+
]
|
|
466
|
+
.filter(Boolean)
|
|
467
|
+
.join(':')
|
|
391
468
|
}
|
|
392
469
|
|
|
393
470
|
/**
|
|
394
471
|
* Returns e.g: `19840621_1705`
|
|
395
472
|
*/
|
|
396
473
|
toStringCompact(seconds = false): string {
|
|
474
|
+
const { year, month, day, hour, minute, second } = this.components()
|
|
475
|
+
|
|
397
476
|
return [
|
|
398
|
-
String(
|
|
399
|
-
String(
|
|
400
|
-
String(
|
|
477
|
+
String(year).padStart(4, '0'),
|
|
478
|
+
String(month).padStart(2, '0'),
|
|
479
|
+
String(day).padStart(2, '0'),
|
|
401
480
|
'_',
|
|
402
|
-
String(
|
|
403
|
-
String(
|
|
404
|
-
seconds ? String(
|
|
481
|
+
String(hour).padStart(2, '0'),
|
|
482
|
+
String(minute).padStart(2, '0'),
|
|
483
|
+
seconds ? String(second).padStart(2, '0') : '',
|
|
405
484
|
].join('')
|
|
406
485
|
}
|
|
407
486
|
|