@naturalcycles/js-lib 14.98.3 → 14.99.2
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/array/array.util.d.ts +10 -1
- package/dist/array/array.util.js +36 -2
- package/dist/datetime/localDate.d.ts +13 -10
- package/dist/datetime/localDate.js +47 -22
- package/dist/datetime/localTime.d.ts +24 -8
- package/dist/datetime/localTime.js +228 -78
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -0
- package/dist/vendor/is.d.ts +2 -0
- package/dist-esm/array/array.util.js +30 -1
- package/dist-esm/datetime/localDate.js +47 -22
- package/dist-esm/datetime/localTime.js +227 -77
- package/dist-esm/index.js +1 -0
- package/package.json +1 -1
- package/src/array/array.util.ts +30 -1
- package/src/datetime/localDate.ts +65 -31
- package/src/datetime/localTime.ts +260 -91
- package/src/index.ts +18 -2
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.localTime = exports.LocalTime = void 0;
|
|
3
|
+
exports.localTime = exports.LocalTime = exports.ISODayOfWeek = void 0;
|
|
4
4
|
const assert_1 = require("../error/assert");
|
|
5
5
|
const time_util_1 = require("../time/time.util");
|
|
6
6
|
const localDate_1 = require("./localDate");
|
|
7
|
+
var ISODayOfWeek;
|
|
8
|
+
(function (ISODayOfWeek) {
|
|
9
|
+
ISODayOfWeek[ISODayOfWeek["MONDAY"] = 1] = "MONDAY";
|
|
10
|
+
ISODayOfWeek[ISODayOfWeek["TUESDAY"] = 2] = "TUESDAY";
|
|
11
|
+
ISODayOfWeek[ISODayOfWeek["WEDNESDAY"] = 3] = "WEDNESDAY";
|
|
12
|
+
ISODayOfWeek[ISODayOfWeek["THURSDAY"] = 4] = "THURSDAY";
|
|
13
|
+
ISODayOfWeek[ISODayOfWeek["FRIDAY"] = 5] = "FRIDAY";
|
|
14
|
+
ISODayOfWeek[ISODayOfWeek["SATURDAY"] = 6] = "SATURDAY";
|
|
15
|
+
ISODayOfWeek[ISODayOfWeek["SUNDAY"] = 7] = "SUNDAY";
|
|
16
|
+
})(ISODayOfWeek = exports.ISODayOfWeek || (exports.ISODayOfWeek = {}));
|
|
17
|
+
const weekStartsOn = 1; // mon, as per ISO
|
|
18
|
+
const MILLISECONDS_IN_WEEK = 604800000;
|
|
19
|
+
const SECONDS_IN_DAY = 86400;
|
|
20
|
+
// const MILLISECONDS_IN_DAY = 86400000
|
|
21
|
+
// const MILLISECONDS_IN_MINUTE = 60000
|
|
22
|
+
const VALID_DAYS_OF_WEEK = new Set([1, 2, 3, 4, 5, 6, 7]);
|
|
7
23
|
/* eslint-disable no-dupe-class-members */
|
|
8
24
|
/**
|
|
9
25
|
* @experimental
|
|
10
26
|
*/
|
|
11
27
|
class LocalTime {
|
|
12
|
-
constructor($date
|
|
28
|
+
constructor($date) {
|
|
13
29
|
this.$date = $date;
|
|
14
|
-
this.utcMode = utcMode;
|
|
15
30
|
}
|
|
16
31
|
/**
|
|
17
32
|
* Parses input String into LocalDate.
|
|
@@ -24,14 +39,6 @@ class LocalTime {
|
|
|
24
39
|
}
|
|
25
40
|
return t;
|
|
26
41
|
}
|
|
27
|
-
utc() {
|
|
28
|
-
this.utcMode = true;
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
local() {
|
|
32
|
-
this.utcMode = false;
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
42
|
/**
|
|
36
43
|
* Returns null if invalid
|
|
37
44
|
*/
|
|
@@ -58,7 +65,7 @@ class LocalTime {
|
|
|
58
65
|
// if (utc) {
|
|
59
66
|
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
60
67
|
// }
|
|
61
|
-
return new LocalTime(date
|
|
68
|
+
return new LocalTime(date);
|
|
62
69
|
}
|
|
63
70
|
static parseToDate(d) {
|
|
64
71
|
if (d instanceof LocalTime)
|
|
@@ -86,52 +93,56 @@ class LocalTime {
|
|
|
86
93
|
return this.parseOrNull(d) !== null;
|
|
87
94
|
}
|
|
88
95
|
static now() {
|
|
89
|
-
return new LocalTime(new Date()
|
|
96
|
+
return new LocalTime(new Date());
|
|
90
97
|
}
|
|
91
98
|
static fromComponents(c) {
|
|
92
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second)
|
|
99
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second));
|
|
93
100
|
}
|
|
94
101
|
get(unit) {
|
|
95
102
|
if (unit === 'year') {
|
|
96
|
-
return this
|
|
103
|
+
return this.$date.getFullYear();
|
|
97
104
|
}
|
|
98
105
|
if (unit === 'month') {
|
|
99
|
-
return
|
|
106
|
+
return this.$date.getMonth() + 1;
|
|
100
107
|
}
|
|
101
108
|
if (unit === 'day') {
|
|
102
|
-
return this
|
|
109
|
+
return this.$date.getDate();
|
|
103
110
|
}
|
|
104
111
|
if (unit === 'hour') {
|
|
105
|
-
return this
|
|
112
|
+
return this.$date.getHours();
|
|
106
113
|
}
|
|
107
114
|
if (unit === 'minute') {
|
|
108
|
-
return this
|
|
115
|
+
return this.$date.getMinutes();
|
|
116
|
+
}
|
|
117
|
+
if (unit === 'week') {
|
|
118
|
+
return getWeek(this.$date);
|
|
109
119
|
}
|
|
110
120
|
// second
|
|
111
|
-
return this
|
|
121
|
+
return this.$date.getSeconds();
|
|
112
122
|
}
|
|
113
123
|
set(unit, v, mutate = false) {
|
|
114
124
|
const t = mutate ? this : this.clone();
|
|
115
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
116
125
|
if (unit === 'year') {
|
|
117
|
-
|
|
126
|
+
t.$date.setFullYear(v);
|
|
118
127
|
}
|
|
119
128
|
else if (unit === 'month') {
|
|
120
|
-
|
|
129
|
+
t.$date.setMonth(v - 1);
|
|
121
130
|
}
|
|
122
131
|
else if (unit === 'day') {
|
|
123
|
-
|
|
132
|
+
t.$date.setDate(v);
|
|
124
133
|
}
|
|
125
134
|
else if (unit === 'hour') {
|
|
126
|
-
|
|
135
|
+
t.$date.setHours(v);
|
|
127
136
|
}
|
|
128
137
|
else if (unit === 'minute') {
|
|
129
|
-
|
|
138
|
+
t.$date.setMinutes(v);
|
|
130
139
|
}
|
|
131
140
|
else if (unit === 'second') {
|
|
132
|
-
|
|
141
|
+
t.$date.setSeconds(v);
|
|
142
|
+
}
|
|
143
|
+
else if (unit === 'week') {
|
|
144
|
+
setWeek(t.$date, v, true);
|
|
133
145
|
}
|
|
134
|
-
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
135
146
|
return t;
|
|
136
147
|
}
|
|
137
148
|
year(v) {
|
|
@@ -140,9 +151,21 @@ class LocalTime {
|
|
|
140
151
|
month(v) {
|
|
141
152
|
return v === undefined ? this.get('month') : this.set('month', v);
|
|
142
153
|
}
|
|
154
|
+
week(v) {
|
|
155
|
+
return v === undefined ? getWeek(this.$date) : this.set('week', v);
|
|
156
|
+
}
|
|
143
157
|
day(v) {
|
|
144
158
|
return v === undefined ? this.get('day') : this.set('day', v);
|
|
145
159
|
}
|
|
160
|
+
dayOfWeek(v) {
|
|
161
|
+
const dow = (this.$date.getDay() || 7);
|
|
162
|
+
if (v === undefined) {
|
|
163
|
+
return dow;
|
|
164
|
+
}
|
|
165
|
+
if (!VALID_DAYS_OF_WEEK.has(v))
|
|
166
|
+
throw new Error(`Invalid dayOfWeek: ${v}`);
|
|
167
|
+
return this.add(v - dow, 'day');
|
|
168
|
+
}
|
|
146
169
|
hour(v) {
|
|
147
170
|
return v === undefined ? this.get('hour') : this.set('hour', v);
|
|
148
171
|
}
|
|
@@ -154,29 +177,31 @@ class LocalTime {
|
|
|
154
177
|
}
|
|
155
178
|
setComponents(c, mutate = false) {
|
|
156
179
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
157
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
158
180
|
if (c.year) {
|
|
159
|
-
|
|
181
|
+
d.setFullYear(c.year);
|
|
160
182
|
}
|
|
161
183
|
if (c.month) {
|
|
162
|
-
|
|
184
|
+
d.setMonth(c.month - 1);
|
|
163
185
|
}
|
|
164
186
|
if (c.day) {
|
|
165
|
-
|
|
187
|
+
d.setDate(c.day);
|
|
166
188
|
}
|
|
167
189
|
if (c.hour !== undefined) {
|
|
168
|
-
|
|
190
|
+
d.setHours(c.hour);
|
|
169
191
|
}
|
|
170
192
|
if (c.minute !== undefined) {
|
|
171
|
-
|
|
193
|
+
d.setMinutes(c.minute);
|
|
172
194
|
}
|
|
173
195
|
if (c.second !== undefined) {
|
|
174
|
-
|
|
196
|
+
d.setSeconds(c.second);
|
|
175
197
|
}
|
|
176
|
-
|
|
177
|
-
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
198
|
+
return mutate ? this : new LocalTime(d);
|
|
178
199
|
}
|
|
179
200
|
add(num, unit, mutate = false) {
|
|
201
|
+
if (unit === 'week') {
|
|
202
|
+
num *= 7;
|
|
203
|
+
unit = 'day';
|
|
204
|
+
}
|
|
180
205
|
return this.set(unit, this.get(unit) + num, mutate);
|
|
181
206
|
}
|
|
182
207
|
subtract(num, unit, mutate = false) {
|
|
@@ -187,21 +212,43 @@ class LocalTime {
|
|
|
187
212
|
}
|
|
188
213
|
diff(other, unit) {
|
|
189
214
|
const date2 = LocalTime.parseToDate(other);
|
|
190
|
-
if (unit === 'year') {
|
|
191
|
-
return this.$date.getFullYear() - date2.getFullYear();
|
|
192
|
-
}
|
|
193
|
-
if (unit === 'month') {
|
|
194
|
-
return ((this.$date.getFullYear() - date2.getFullYear()) * 12 +
|
|
195
|
-
this.$date.getMonth() -
|
|
196
|
-
date2.getMonth());
|
|
197
|
-
}
|
|
198
215
|
const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000;
|
|
216
|
+
if (!secDiff)
|
|
217
|
+
return 0;
|
|
218
|
+
if (unit === 'year' || unit === 'month') {
|
|
219
|
+
const sign = secDiff > 0 ? 1 : -1;
|
|
220
|
+
// Put items in descending order: "big minus small"
|
|
221
|
+
const [big, small] = sign === 1 ? [this.$date, date2] : [date2, this.$date];
|
|
222
|
+
if (unit === 'year') {
|
|
223
|
+
let years = big.getFullYear() - small.getFullYear();
|
|
224
|
+
const big2 = new Date(big);
|
|
225
|
+
const small2 = new Date(small);
|
|
226
|
+
big2.setFullYear(1584);
|
|
227
|
+
small2.setFullYear(1584);
|
|
228
|
+
if (big2 < small2)
|
|
229
|
+
years--;
|
|
230
|
+
return years * sign || 0;
|
|
231
|
+
}
|
|
232
|
+
if (unit === 'month') {
|
|
233
|
+
let months = (big.getFullYear() - small.getFullYear()) * 12 + big.getMonth() - small.getMonth();
|
|
234
|
+
const big2 = new Date(big);
|
|
235
|
+
const small2 = new Date(small);
|
|
236
|
+
big2.setFullYear(1584, 0);
|
|
237
|
+
small2.setFullYear(1584, 0);
|
|
238
|
+
if (big2 < small2)
|
|
239
|
+
months--;
|
|
240
|
+
return months * sign || 0;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
199
243
|
let r;
|
|
200
244
|
if (unit === 'day') {
|
|
201
|
-
r = secDiff /
|
|
245
|
+
r = secDiff / SECONDS_IN_DAY;
|
|
246
|
+
}
|
|
247
|
+
else if (unit === 'week') {
|
|
248
|
+
r = secDiff / (7 * 24 * 60 * 60);
|
|
202
249
|
}
|
|
203
250
|
else if (unit === 'hour') {
|
|
204
|
-
r = secDiff /
|
|
251
|
+
r = secDiff / 3600;
|
|
205
252
|
}
|
|
206
253
|
else if (unit === 'minute') {
|
|
207
254
|
r = secDiff / 60;
|
|
@@ -210,32 +257,62 @@ class LocalTime {
|
|
|
210
257
|
// unit === 'second'
|
|
211
258
|
r = secDiff;
|
|
212
259
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return 0;
|
|
216
|
-
return r;
|
|
260
|
+
// `|| 0` is to avoid returning -0
|
|
261
|
+
return Math.trunc(r) || 0;
|
|
217
262
|
}
|
|
218
263
|
startOf(unit, mutate = false) {
|
|
219
264
|
if (unit === 'second')
|
|
220
265
|
return this;
|
|
221
266
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
222
|
-
d.
|
|
223
|
-
d.setSeconds(0);
|
|
224
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
267
|
+
d.setSeconds(0, 0);
|
|
225
268
|
if (unit !== 'minute') {
|
|
226
|
-
|
|
269
|
+
d.setMinutes(0);
|
|
227
270
|
if (unit !== 'hour') {
|
|
228
|
-
|
|
271
|
+
d.setHours(0);
|
|
229
272
|
if (unit !== 'day') {
|
|
230
|
-
|
|
231
|
-
if (unit
|
|
232
|
-
|
|
273
|
+
// year, month or week
|
|
274
|
+
if (unit === 'year') {
|
|
275
|
+
d.setMonth(0);
|
|
276
|
+
d.setDate(1);
|
|
277
|
+
}
|
|
278
|
+
else if (unit === 'month') {
|
|
279
|
+
d.setDate(1);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
// week
|
|
283
|
+
startOfWeek(d, true);
|
|
233
284
|
}
|
|
234
285
|
}
|
|
235
286
|
}
|
|
236
287
|
}
|
|
237
|
-
|
|
238
|
-
|
|
288
|
+
return mutate ? this : new LocalTime(d);
|
|
289
|
+
}
|
|
290
|
+
endOf(unit, mutate = false) {
|
|
291
|
+
if (unit === 'second')
|
|
292
|
+
return this;
|
|
293
|
+
const d = mutate ? this.$date : new Date(this.$date);
|
|
294
|
+
d.setSeconds(59, 0);
|
|
295
|
+
if (unit !== 'minute') {
|
|
296
|
+
d.setMinutes(59);
|
|
297
|
+
if (unit !== 'hour') {
|
|
298
|
+
d.setHours(23);
|
|
299
|
+
if (unit !== 'day') {
|
|
300
|
+
// year, month or week
|
|
301
|
+
if (unit === 'year') {
|
|
302
|
+
d.setMonth(11);
|
|
303
|
+
}
|
|
304
|
+
if (unit === 'week') {
|
|
305
|
+
endOfWeek(d, true);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
// year or month
|
|
309
|
+
const lastDay = localDate_1.LocalDate.getMonthLength(d.getFullYear(), d.getMonth() + 1);
|
|
310
|
+
d.setDate(lastDay);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return mutate ? this : new LocalTime(d);
|
|
239
316
|
}
|
|
240
317
|
static sort(items, mutate = false, descending = false) {
|
|
241
318
|
const mod = descending ? -1 : 1;
|
|
@@ -252,14 +329,18 @@ class LocalTime {
|
|
|
252
329
|
}
|
|
253
330
|
static earliest(items) {
|
|
254
331
|
(0, assert_1._assert)(items.length, 'LocalTime.earliest called on empty array');
|
|
255
|
-
return items
|
|
332
|
+
return items
|
|
333
|
+
.map(i => LocalTime.of(i))
|
|
334
|
+
.reduce((min, item) => (min.isSameOrBefore(item) ? min : item));
|
|
256
335
|
}
|
|
257
336
|
static latestOrUndefined(items) {
|
|
258
337
|
return items.length ? LocalTime.latest(items) : undefined;
|
|
259
338
|
}
|
|
260
339
|
static latest(items) {
|
|
261
340
|
(0, assert_1._assert)(items.length, 'LocalTime.latest called on empty array');
|
|
262
|
-
return items
|
|
341
|
+
return items
|
|
342
|
+
.map(i => LocalTime.of(i))
|
|
343
|
+
.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
|
|
263
344
|
}
|
|
264
345
|
isSame(d) {
|
|
265
346
|
return this.cmp(d) === 0;
|
|
@@ -299,18 +380,7 @@ class LocalTime {
|
|
|
299
380
|
return 0;
|
|
300
381
|
return t1 < t2 ? -1 : 1;
|
|
301
382
|
}
|
|
302
|
-
// todo: endOf
|
|
303
383
|
components() {
|
|
304
|
-
if (this.utcMode) {
|
|
305
|
-
return {
|
|
306
|
-
year: this.$date.getUTCFullYear(),
|
|
307
|
-
month: this.$date.getUTCMonth() + 1,
|
|
308
|
-
day: this.$date.getUTCDate(),
|
|
309
|
-
hour: this.$date.getUTCHours(),
|
|
310
|
-
minute: this.$date.getUTCMinutes(),
|
|
311
|
-
second: this.$date.getSeconds(),
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
384
|
return {
|
|
315
385
|
year: this.$date.getFullYear(),
|
|
316
386
|
month: this.$date.getMonth() + 1,
|
|
@@ -333,7 +403,7 @@ class LocalTime {
|
|
|
333
403
|
return this.$date;
|
|
334
404
|
}
|
|
335
405
|
clone() {
|
|
336
|
-
return new LocalTime(new Date(this.$date)
|
|
406
|
+
return new LocalTime(new Date(this.$date));
|
|
337
407
|
}
|
|
338
408
|
unix() {
|
|
339
409
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
@@ -345,9 +415,6 @@ class LocalTime {
|
|
|
345
415
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
346
416
|
}
|
|
347
417
|
toLocalDate() {
|
|
348
|
-
if (this.utcMode) {
|
|
349
|
-
return localDate_1.LocalDate.create(this.$date.getUTCFullYear(), this.$date.getUTCMonth() + 1, this.$date.getUTCDate());
|
|
350
|
-
}
|
|
351
418
|
return localDate_1.LocalDate.create(this.$date.getFullYear(), this.$date.getMonth() + 1, this.$date.getDate());
|
|
352
419
|
}
|
|
353
420
|
toPretty(seconds = true) {
|
|
@@ -424,6 +491,9 @@ class LocalTime {
|
|
|
424
491
|
toJSON() {
|
|
425
492
|
return this.unix();
|
|
426
493
|
}
|
|
494
|
+
format(fmt) {
|
|
495
|
+
return fmt(this);
|
|
496
|
+
}
|
|
427
497
|
}
|
|
428
498
|
exports.LocalTime = LocalTime;
|
|
429
499
|
/**
|
|
@@ -433,3 +503,83 @@ function localTime(d) {
|
|
|
433
503
|
return d ? LocalTime.of(d) : LocalTime.now();
|
|
434
504
|
}
|
|
435
505
|
exports.localTime = localTime;
|
|
506
|
+
// based on: https://github.com/date-fns/date-fns/blob/master/src/getISOWeek/index.ts
|
|
507
|
+
function getWeek(date) {
|
|
508
|
+
const diff = startOfWeek(date).getTime() - startOfWeekYear(date).getTime();
|
|
509
|
+
return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;
|
|
510
|
+
}
|
|
511
|
+
function setWeek(date, week, mutate = false) {
|
|
512
|
+
const d = mutate ? date : new Date(date);
|
|
513
|
+
const diff = getWeek(d) - week;
|
|
514
|
+
d.setDate(d.getDate() - diff * 7);
|
|
515
|
+
return d;
|
|
516
|
+
}
|
|
517
|
+
// based on: https://github.com/date-fns/date-fns/blob/master/src/startOfISOWeekYear/index.ts
|
|
518
|
+
function startOfWeekYear(date) {
|
|
519
|
+
const year = getWeekYear(date);
|
|
520
|
+
const fourthOfJanuary = new Date(0);
|
|
521
|
+
fourthOfJanuary.setFullYear(year, 0, 4);
|
|
522
|
+
fourthOfJanuary.setHours(0, 0, 0, 0);
|
|
523
|
+
return startOfWeek(fourthOfJanuary, true);
|
|
524
|
+
}
|
|
525
|
+
// based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/getISOWeekYear/index.ts
|
|
526
|
+
function getWeekYear(date) {
|
|
527
|
+
const year = date.getFullYear();
|
|
528
|
+
const fourthOfJanuaryOfNextYear = new Date(0);
|
|
529
|
+
fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);
|
|
530
|
+
fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);
|
|
531
|
+
const startOfNextYear = startOfWeek(fourthOfJanuaryOfNextYear, true);
|
|
532
|
+
const fourthOfJanuaryOfThisYear = new Date(0);
|
|
533
|
+
fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4);
|
|
534
|
+
fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0);
|
|
535
|
+
const startOfThisYear = startOfWeek(fourthOfJanuaryOfThisYear, true);
|
|
536
|
+
if (date.getTime() >= startOfNextYear.getTime()) {
|
|
537
|
+
return year + 1;
|
|
538
|
+
}
|
|
539
|
+
else if (date.getTime() >= startOfThisYear.getTime()) {
|
|
540
|
+
return year;
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
return year - 1;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
// function setWeekYear(
|
|
547
|
+
// date: Date,
|
|
548
|
+
// year: number,
|
|
549
|
+
// ): Date {
|
|
550
|
+
// const diff = differenceInCalendarDays(date, startOfWeekYear(date))
|
|
551
|
+
// const fourthOfJanuary = new Date(0)
|
|
552
|
+
// fourthOfJanuary.setFullYear(year, 0, 4)
|
|
553
|
+
// fourthOfJanuary.setHours(0, 0, 0, 0)
|
|
554
|
+
// date = startOfWeekYear(fourthOfJanuary)
|
|
555
|
+
// date.setDate(date.getDate() + diff)
|
|
556
|
+
// return date
|
|
557
|
+
// }
|
|
558
|
+
// function differenceInCalendarDays(
|
|
559
|
+
// dateLeft: Date,
|
|
560
|
+
// dateRight: Date,
|
|
561
|
+
// ): number {
|
|
562
|
+
// return Math.round((startOfDay(dateLeft).getTime() - startOfDay(dateRight).getTime()) / MILLISECONDS_IN_DAY)
|
|
563
|
+
// }
|
|
564
|
+
// function startOfDay(date: Date, mutate = false): Date {
|
|
565
|
+
// const d = mutate ? date : new Date(date)
|
|
566
|
+
// d.setHours(0, 0, 0, 0)
|
|
567
|
+
// return d
|
|
568
|
+
// }
|
|
569
|
+
// based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/startOfWeek/index.ts
|
|
570
|
+
function startOfWeek(date, mutate = false) {
|
|
571
|
+
const d = mutate ? date : new Date(date);
|
|
572
|
+
const day = d.getDay();
|
|
573
|
+
const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
|
|
574
|
+
d.setDate(d.getDate() - diff);
|
|
575
|
+
d.setHours(0, 0, 0, 0);
|
|
576
|
+
return d;
|
|
577
|
+
}
|
|
578
|
+
// based on: https://github.com/date-fns/date-fns/blob/master/src/endOfWeek/index.ts
|
|
579
|
+
function endOfWeek(date, mutate = false) {
|
|
580
|
+
const d = mutate ? date : new Date(date);
|
|
581
|
+
const day = d.getDay();
|
|
582
|
+
const diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);
|
|
583
|
+
d.setDate(d.getDate() + diff);
|
|
584
|
+
return d;
|
|
585
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -64,9 +64,9 @@ export * from './datetime/localDate';
|
|
|
64
64
|
export * from './datetime/localTime';
|
|
65
65
|
export * from './datetime/dateInterval';
|
|
66
66
|
export * from './datetime/timeInterval';
|
|
67
|
-
import { LocalDateConfig, LocalDateUnit, Inclusiveness } from './datetime/localDate';
|
|
68
|
-
import { LocalTimeConfig, LocalTimeUnit, LocalTimeComponents } from './datetime/localTime';
|
|
67
|
+
import { LocalDateConfig, LocalDateFormatter, LocalDateUnit, LocalDateUnitStrict, Inclusiveness } from './datetime/localDate';
|
|
68
|
+
import { LocalTimeConfig, LocalTimeFormatter, LocalTimeUnit, LocalTimeComponents, ISODayOfWeek } from './datetime/localTime';
|
|
69
69
|
import { DateIntervalConfig, DateIntervalString } from './datetime/dateInterval';
|
|
70
70
|
import { TimeIntervalConfig, TimeIntervalString } from './datetime/timeInterval';
|
|
71
|
-
export type { DateIntervalConfig, DateIntervalString, TimeIntervalConfig, TimeIntervalString, LocalDateConfig, LocalDateUnit, Inclusiveness, LocalTimeConfig, LocalTimeUnit, LocalTimeComponents, AbortableMapper, AbortablePredicate, AbortableAsyncPredicate, AbortableAsyncMapper, PQueueCfg, MemoCache, AsyncMemoCache, PromiseDecoratorCfg, PromiseDecoratorResp, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Admin401ErrorData, Admin403ErrorData, StringMap, PromiseMap, AnyObject, AnyFunction, ValuesOf, ValueOf, KeyValueTuple, ObjectMapper, ObjectPredicate, InstanceId, IsoDate, IsoDateString, IsoDateTimeString, Reviver, PMapOptions, Mapper, AsyncMapper, Predicate, AsyncPredicate, BatchResult, DeferredPromise, PRetryOptions, PTimeoutOptions, TryCatchOptions, StringifyAnyOptions, JsonStringifyFunction, Merge, ReadonlyDeep, Promisable, Simplify, ConditionalPick, ConditionalExcept, Class, UnixTimestampNumber, UnixTimestamp, Integer, BaseDBEntity, SavedDBEntity, Saved, Unsaved, UnsavedId, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, CommonLogLevel, CommonLogWithLevelFunction, CommonLogFunction, CommonLogger, };
|
|
71
|
+
export type { DateIntervalConfig, DateIntervalString, TimeIntervalConfig, TimeIntervalString, LocalDateConfig, LocalDateFormatter, LocalDateUnit, LocalDateUnitStrict, Inclusiveness, LocalTimeConfig, LocalTimeFormatter, LocalTimeUnit, ISODayOfWeek, LocalTimeComponents, AbortableMapper, AbortablePredicate, AbortableAsyncPredicate, AbortableAsyncMapper, PQueueCfg, MemoCache, AsyncMemoCache, PromiseDecoratorCfg, PromiseDecoratorResp, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Admin401ErrorData, Admin403ErrorData, StringMap, PromiseMap, AnyObject, AnyFunction, ValuesOf, ValueOf, KeyValueTuple, ObjectMapper, ObjectPredicate, InstanceId, IsoDate, IsoDateString, IsoDateTimeString, Reviver, PMapOptions, Mapper, AsyncMapper, Predicate, AsyncPredicate, BatchResult, DeferredPromise, PRetryOptions, PTimeoutOptions, TryCatchOptions, StringifyAnyOptions, JsonStringifyFunction, Merge, ReadonlyDeep, Promisable, Simplify, ConditionalPick, ConditionalExcept, Class, UnixTimestampNumber, UnixTimestamp, Integer, BaseDBEntity, SavedDBEntity, Saved, Unsaved, UnsavedId, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, CommonLogLevel, CommonLogWithLevelFunction, CommonLogFunction, CommonLogger, };
|
|
72
72
|
export { is, _createPromiseDecorator, _stringMapValues, _stringMapEntries, _objectKeys, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pRetryFn, pTimeout, pTimeoutFn, _tryCatch, _TryCatch, _stringifyAny, jsonSchema, JsonSchemaAnyBuilder, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, PQueue, END, SKIP, };
|
package/dist/index.js
CHANGED
|
@@ -96,3 +96,4 @@ tslib_1.__exportStar(require("./datetime/localDate"), exports);
|
|
|
96
96
|
tslib_1.__exportStar(require("./datetime/localTime"), exports);
|
|
97
97
|
tslib_1.__exportStar(require("./datetime/dateInterval"), exports);
|
|
98
98
|
tslib_1.__exportStar(require("./datetime/timeInterval"), exports);
|
|
99
|
+
const localTime_1 = require("./datetime/localTime");
|
package/dist/vendor/is.d.ts
CHANGED
|
@@ -237,8 +237,37 @@ export function _shuffle(array, mutate = false) {
|
|
|
237
237
|
return a;
|
|
238
238
|
}
|
|
239
239
|
/**
|
|
240
|
-
* Returns last item of
|
|
240
|
+
* Returns last item of non-empty array.
|
|
241
|
+
* Throws if array is empty.
|
|
241
242
|
*/
|
|
242
243
|
export function _last(array) {
|
|
244
|
+
if (!array.length)
|
|
245
|
+
throw new Error('_last called on empty array');
|
|
246
|
+
return array[array.length - 1];
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Returns last item of the array (or undefined if array is empty).
|
|
250
|
+
*/
|
|
251
|
+
export function _lastOrUndefined(array) {
|
|
243
252
|
return array[array.length - 1];
|
|
244
253
|
}
|
|
254
|
+
export function _minOrUndefined(array) {
|
|
255
|
+
if (!array.length)
|
|
256
|
+
return;
|
|
257
|
+
return _min(array);
|
|
258
|
+
}
|
|
259
|
+
export function _min(array) {
|
|
260
|
+
if (!array.length)
|
|
261
|
+
throw new Error('_min called on empty array');
|
|
262
|
+
return array.reduce((min, item) => (min <= item ? min : item));
|
|
263
|
+
}
|
|
264
|
+
export function _maxOrUndefined(array) {
|
|
265
|
+
if (!array.length)
|
|
266
|
+
return;
|
|
267
|
+
return _max(array);
|
|
268
|
+
}
|
|
269
|
+
export function _max(array) {
|
|
270
|
+
if (!array.length)
|
|
271
|
+
throw new Error('_max called on empty array');
|
|
272
|
+
return array.reduce((max, item) => (max >= item ? max : item));
|
|
273
|
+
}
|
|
@@ -87,16 +87,24 @@ export class LocalDate {
|
|
|
87
87
|
}
|
|
88
88
|
static earliest(items) {
|
|
89
89
|
_assert(items.length, 'LocalDate.earliest called on empty array');
|
|
90
|
-
return items
|
|
90
|
+
return items
|
|
91
|
+
.map(i => LocalDate.of(i))
|
|
92
|
+
.reduce((min, item) => (min.isSameOrBefore(item) ? min : item));
|
|
91
93
|
}
|
|
92
94
|
static latestOrUndefined(items) {
|
|
93
95
|
return items.length ? LocalDate.latest(items) : undefined;
|
|
94
96
|
}
|
|
95
97
|
static latest(items) {
|
|
96
98
|
_assert(items.length, 'LocalDate.latest called on empty array');
|
|
97
|
-
return items
|
|
99
|
+
return items
|
|
100
|
+
.map(i => LocalDate.of(i))
|
|
101
|
+
.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
|
|
98
102
|
}
|
|
99
103
|
static range(min, max, incl = '[)', step = 1, stepUnit = 'day') {
|
|
104
|
+
if (stepUnit === 'week') {
|
|
105
|
+
step *= 7;
|
|
106
|
+
stepUnit = 'day';
|
|
107
|
+
}
|
|
100
108
|
const dates = [];
|
|
101
109
|
const $min = LocalDate.of(min);
|
|
102
110
|
const $max = LocalDate.of(max).startOf(stepUnit);
|
|
@@ -194,44 +202,58 @@ export class LocalDate {
|
|
|
194
202
|
return Math.abs(this.diff(d, unit));
|
|
195
203
|
}
|
|
196
204
|
/**
|
|
197
|
-
* Returns the number of **full** units difference (aka `Math.
|
|
205
|
+
* Returns the number of **full** units difference (aka `Math.floor`).
|
|
198
206
|
*
|
|
199
207
|
* a.diff(b) means "a minus b"
|
|
200
208
|
*/
|
|
201
209
|
diff(d, unit) {
|
|
202
210
|
d = LocalDate.of(d);
|
|
211
|
+
const sign = this.cmp(d);
|
|
212
|
+
if (!sign)
|
|
213
|
+
return 0;
|
|
214
|
+
// Put items in descending order: "big minus small"
|
|
215
|
+
const [big, small] = sign === 1 ? [this, d] : [d, this];
|
|
203
216
|
if (unit === 'year') {
|
|
204
|
-
|
|
217
|
+
let years = big.$year - small.$year;
|
|
218
|
+
if (big.$month < small.$month || (big.$month === small.$month && big.$day < small.$day)) {
|
|
219
|
+
years--;
|
|
220
|
+
}
|
|
221
|
+
return years * sign || 0;
|
|
205
222
|
}
|
|
206
223
|
if (unit === 'month') {
|
|
207
|
-
|
|
224
|
+
let months = (big.$year - small.$year) * 12 + (big.$month - small.$month);
|
|
225
|
+
if (big.$day < small.$day)
|
|
226
|
+
months--;
|
|
227
|
+
return months * sign || 0;
|
|
208
228
|
}
|
|
209
|
-
// unit is 'day'
|
|
210
|
-
let days =
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
229
|
+
// unit is 'day' or 'week'
|
|
230
|
+
let days = big.$day - small.$day;
|
|
231
|
+
// If small date is after 1st of March - next year's "leapness" should be used
|
|
232
|
+
const offsetYear = small.$month >= 3 ? 1 : 0;
|
|
233
|
+
for (let year = small.$year; year < big.$year; year++) {
|
|
234
|
+
days += LocalDate.getYearLength(year + offsetYear);
|
|
215
235
|
}
|
|
216
|
-
|
|
217
|
-
for (let
|
|
218
|
-
days
|
|
236
|
+
if (small.$month < big.$month) {
|
|
237
|
+
for (let month = small.$month; month < big.$month; month++) {
|
|
238
|
+
days += LocalDate.getMonthLength(big.$year, month);
|
|
219
239
|
}
|
|
220
240
|
}
|
|
221
|
-
if (
|
|
222
|
-
for (let month =
|
|
223
|
-
days
|
|
241
|
+
else if (big.$month < small.$month) {
|
|
242
|
+
for (let month = big.$month; month < small.$month; month++) {
|
|
243
|
+
days -= LocalDate.getMonthLength(big.$year, month);
|
|
224
244
|
}
|
|
225
245
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
days -= LocalDate.getMonthLength(d.$year, month);
|
|
229
|
-
}
|
|
246
|
+
if (unit === 'week') {
|
|
247
|
+
return Math.trunc(days / 7) * sign || 0;
|
|
230
248
|
}
|
|
231
|
-
return days;
|
|
249
|
+
return days * sign || 0;
|
|
232
250
|
}
|
|
233
251
|
add(num, unit, mutate = false) {
|
|
234
252
|
let { $day, $month, $year } = this;
|
|
253
|
+
if (unit === 'week') {
|
|
254
|
+
num *= 7;
|
|
255
|
+
unit = 'day';
|
|
256
|
+
}
|
|
235
257
|
if (unit === 'day') {
|
|
236
258
|
$day += num;
|
|
237
259
|
}
|
|
@@ -361,6 +383,9 @@ export class LocalDate {
|
|
|
361
383
|
toJSON() {
|
|
362
384
|
return this.toString();
|
|
363
385
|
}
|
|
386
|
+
format(fmt) {
|
|
387
|
+
return fmt(this);
|
|
388
|
+
}
|
|
364
389
|
}
|
|
365
390
|
/**
|
|
366
391
|
* Shortcut wrapper around `LocalDate.parse` / `LocalDate.today`
|