@naturalcycles/js-lib 14.99.1 → 14.99.4
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.js +37 -22
- package/dist/datetime/localTime.d.ts +0 -3
- package/dist/datetime/localTime.js +80 -120
- package/dist-esm/datetime/localDate.js +37 -22
- package/dist-esm/datetime/localTime.js +81 -120
- package/package.json +1 -1
- package/src/datetime/localDate.ts +42 -23
- package/src/datetime/localTime.ts +92 -133
|
@@ -22,9 +22,8 @@ const VALID_DAYS_OF_WEEK = new Set([1, 2, 3, 4, 5, 6, 7]);
|
|
|
22
22
|
* @experimental
|
|
23
23
|
*/
|
|
24
24
|
export class LocalTime {
|
|
25
|
-
constructor($date
|
|
25
|
+
constructor($date) {
|
|
26
26
|
this.$date = $date;
|
|
27
|
-
this.utcMode = utcMode;
|
|
28
27
|
}
|
|
29
28
|
/**
|
|
30
29
|
* Parses input String into LocalDate.
|
|
@@ -37,14 +36,6 @@ export class LocalTime {
|
|
|
37
36
|
}
|
|
38
37
|
return t;
|
|
39
38
|
}
|
|
40
|
-
utc() {
|
|
41
|
-
this.utcMode = true;
|
|
42
|
-
return this;
|
|
43
|
-
}
|
|
44
|
-
local() {
|
|
45
|
-
this.utcMode = false;
|
|
46
|
-
return this;
|
|
47
|
-
}
|
|
48
39
|
/**
|
|
49
40
|
* Returns null if invalid
|
|
50
41
|
*/
|
|
@@ -71,7 +62,7 @@ export class LocalTime {
|
|
|
71
62
|
// if (utc) {
|
|
72
63
|
// date.setMinutes(date.getMinutes() + date.getTimezoneOffset())
|
|
73
64
|
// }
|
|
74
|
-
return new LocalTime(date
|
|
65
|
+
return new LocalTime(date);
|
|
75
66
|
}
|
|
76
67
|
static parseToDate(d) {
|
|
77
68
|
if (d instanceof LocalTime)
|
|
@@ -99,58 +90,56 @@ export class LocalTime {
|
|
|
99
90
|
return this.parseOrNull(d) !== null;
|
|
100
91
|
}
|
|
101
92
|
static now() {
|
|
102
|
-
return new LocalTime(new Date()
|
|
93
|
+
return new LocalTime(new Date());
|
|
103
94
|
}
|
|
104
95
|
static fromComponents(c) {
|
|
105
|
-
return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second
|
|
96
|
+
return new LocalTime(new Date(c.year, c.month - 1, c.day || 1, c.hour || 0, c.minute || 0, c.second || 0));
|
|
106
97
|
}
|
|
107
98
|
get(unit) {
|
|
108
99
|
if (unit === 'year') {
|
|
109
|
-
return this
|
|
100
|
+
return this.$date.getFullYear();
|
|
110
101
|
}
|
|
111
102
|
if (unit === 'month') {
|
|
112
|
-
return
|
|
103
|
+
return this.$date.getMonth() + 1;
|
|
113
104
|
}
|
|
114
105
|
if (unit === 'day') {
|
|
115
|
-
return this
|
|
106
|
+
return this.$date.getDate();
|
|
116
107
|
}
|
|
117
108
|
if (unit === 'hour') {
|
|
118
|
-
return this
|
|
109
|
+
return this.$date.getHours();
|
|
119
110
|
}
|
|
120
111
|
if (unit === 'minute') {
|
|
121
|
-
return this
|
|
112
|
+
return this.$date.getMinutes();
|
|
122
113
|
}
|
|
123
114
|
if (unit === 'week') {
|
|
124
115
|
return getWeek(this.$date);
|
|
125
116
|
}
|
|
126
117
|
// second
|
|
127
|
-
return this
|
|
118
|
+
return this.$date.getSeconds();
|
|
128
119
|
}
|
|
129
120
|
set(unit, v, mutate = false) {
|
|
130
121
|
const t = mutate ? this : this.clone();
|
|
131
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
132
122
|
if (unit === 'year') {
|
|
133
|
-
|
|
123
|
+
t.$date.setFullYear(v);
|
|
134
124
|
}
|
|
135
125
|
else if (unit === 'month') {
|
|
136
|
-
|
|
126
|
+
t.$date.setMonth(v - 1);
|
|
137
127
|
}
|
|
138
128
|
else if (unit === 'day') {
|
|
139
|
-
|
|
129
|
+
t.$date.setDate(v);
|
|
140
130
|
}
|
|
141
131
|
else if (unit === 'hour') {
|
|
142
|
-
|
|
132
|
+
t.$date.setHours(v);
|
|
143
133
|
}
|
|
144
134
|
else if (unit === 'minute') {
|
|
145
|
-
|
|
135
|
+
t.$date.setMinutes(v);
|
|
146
136
|
}
|
|
147
137
|
else if (unit === 'second') {
|
|
148
|
-
|
|
138
|
+
t.$date.setSeconds(v);
|
|
149
139
|
}
|
|
150
140
|
else if (unit === 'week') {
|
|
151
141
|
setWeek(t.$date, v, true);
|
|
152
142
|
}
|
|
153
|
-
/* eslint-enable @typescript-eslint/no-unused-expressions */
|
|
154
143
|
return t;
|
|
155
144
|
}
|
|
156
145
|
year(v) {
|
|
@@ -184,34 +173,32 @@ export class LocalTime {
|
|
|
184
173
|
return v === undefined ? this.get('second') : this.set('second', v);
|
|
185
174
|
}
|
|
186
175
|
setComponents(c, mutate = false) {
|
|
176
|
+
var _a;
|
|
187
177
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
188
|
-
|
|
189
|
-
if (c.year) {
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
if (c.month) {
|
|
193
|
-
this.utcMode ? d.setUTCMonth(c.month - 1) : d.setMonth(c.month - 1);
|
|
194
|
-
}
|
|
195
|
-
if (c.day) {
|
|
196
|
-
this.utcMode ? d.setUTCDate(c.day) : d.setDate(c.day);
|
|
178
|
+
// Year, month and day set all-at-once, to avoid 30/31 (and 28/29) mishap
|
|
179
|
+
if (c.day || c.month !== undefined || c.year !== undefined) {
|
|
180
|
+
d.setFullYear((_a = c.year) !== null && _a !== void 0 ? _a : d.getFullYear(), c.month ? c.month - 1 : d.getMonth(), c.day || d.getDate());
|
|
197
181
|
}
|
|
198
182
|
if (c.hour !== undefined) {
|
|
199
|
-
|
|
183
|
+
d.setHours(c.hour);
|
|
200
184
|
}
|
|
201
185
|
if (c.minute !== undefined) {
|
|
202
|
-
|
|
186
|
+
d.setMinutes(c.minute);
|
|
203
187
|
}
|
|
204
188
|
if (c.second !== undefined) {
|
|
205
|
-
|
|
189
|
+
d.setSeconds(c.second);
|
|
206
190
|
}
|
|
207
|
-
|
|
208
|
-
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
191
|
+
return mutate ? this : new LocalTime(d);
|
|
209
192
|
}
|
|
210
193
|
add(num, unit, mutate = false) {
|
|
211
194
|
if (unit === 'week') {
|
|
212
195
|
num *= 7;
|
|
213
196
|
unit = 'day';
|
|
214
197
|
}
|
|
198
|
+
if (unit === 'year' || unit === 'month') {
|
|
199
|
+
const d = addMonths(this.$date, unit === 'month' ? num : num * 12, mutate);
|
|
200
|
+
return mutate ? this : LocalTime.of(d);
|
|
201
|
+
}
|
|
215
202
|
return this.set(unit, this.get(unit) + num, mutate);
|
|
216
203
|
}
|
|
217
204
|
subtract(num, unit, mutate = false) {
|
|
@@ -225,33 +212,14 @@ export class LocalTime {
|
|
|
225
212
|
const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000;
|
|
226
213
|
if (!secDiff)
|
|
227
214
|
return 0;
|
|
228
|
-
if (unit === 'year' || unit === 'month') {
|
|
229
|
-
const sign = secDiff > 0 ? 1 : -1;
|
|
230
|
-
// Put items in descending order: "big minus small"
|
|
231
|
-
const [big, small] = sign === 1 ? [this.$date, date2] : [date2, this.$date];
|
|
232
|
-
if (unit === 'year') {
|
|
233
|
-
let years = big.getFullYear() - small.getFullYear();
|
|
234
|
-
const big2 = new Date(big);
|
|
235
|
-
const small2 = new Date(small);
|
|
236
|
-
big2.setFullYear(1584);
|
|
237
|
-
small2.setFullYear(1584);
|
|
238
|
-
if (big2 < small2)
|
|
239
|
-
years--;
|
|
240
|
-
return years * sign || 0;
|
|
241
|
-
}
|
|
242
|
-
if (unit === 'month') {
|
|
243
|
-
let months = (big.getFullYear() - small.getFullYear()) * 12 + big.getMonth() - small.getMonth();
|
|
244
|
-
const big2 = new Date(big);
|
|
245
|
-
const small2 = new Date(small);
|
|
246
|
-
big2.setFullYear(1584, 0);
|
|
247
|
-
small2.setFullYear(1584, 0);
|
|
248
|
-
if (big2 < small2)
|
|
249
|
-
months--;
|
|
250
|
-
return months * sign || 0;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
215
|
let r;
|
|
254
|
-
if (unit === '
|
|
216
|
+
if (unit === 'year') {
|
|
217
|
+
r = differenceInMonths(this.getDate(), date2) / 12;
|
|
218
|
+
}
|
|
219
|
+
else if (unit === 'month') {
|
|
220
|
+
r = differenceInMonths(this.getDate(), date2);
|
|
221
|
+
}
|
|
222
|
+
else if (unit === 'day') {
|
|
255
223
|
r = secDiff / SECONDS_IN_DAY;
|
|
256
224
|
}
|
|
257
225
|
else if (unit === 'week') {
|
|
@@ -275,19 +243,18 @@ export class LocalTime {
|
|
|
275
243
|
return this;
|
|
276
244
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
277
245
|
d.setSeconds(0, 0);
|
|
278
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
279
246
|
if (unit !== 'minute') {
|
|
280
|
-
|
|
247
|
+
d.setMinutes(0);
|
|
281
248
|
if (unit !== 'hour') {
|
|
282
|
-
|
|
249
|
+
d.setHours(0);
|
|
283
250
|
if (unit !== 'day') {
|
|
284
251
|
// year, month or week
|
|
285
252
|
if (unit === 'year') {
|
|
286
|
-
|
|
287
|
-
|
|
253
|
+
d.setMonth(0);
|
|
254
|
+
d.setDate(1);
|
|
288
255
|
}
|
|
289
256
|
else if (unit === 'month') {
|
|
290
|
-
|
|
257
|
+
d.setDate(1);
|
|
291
258
|
}
|
|
292
259
|
else {
|
|
293
260
|
// week
|
|
@@ -296,23 +263,21 @@ export class LocalTime {
|
|
|
296
263
|
}
|
|
297
264
|
}
|
|
298
265
|
}
|
|
299
|
-
|
|
300
|
-
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
266
|
+
return mutate ? this : new LocalTime(d);
|
|
301
267
|
}
|
|
302
268
|
endOf(unit, mutate = false) {
|
|
303
269
|
if (unit === 'second')
|
|
304
270
|
return this;
|
|
305
271
|
const d = mutate ? this.$date : new Date(this.$date);
|
|
306
272
|
d.setSeconds(59, 0);
|
|
307
|
-
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
308
273
|
if (unit !== 'minute') {
|
|
309
|
-
|
|
274
|
+
d.setMinutes(59);
|
|
310
275
|
if (unit !== 'hour') {
|
|
311
|
-
|
|
276
|
+
d.setHours(23);
|
|
312
277
|
if (unit !== 'day') {
|
|
313
278
|
// year, month or week
|
|
314
279
|
if (unit === 'year') {
|
|
315
|
-
|
|
280
|
+
d.setMonth(11);
|
|
316
281
|
}
|
|
317
282
|
if (unit === 'week') {
|
|
318
283
|
endOfWeek(d, true);
|
|
@@ -320,13 +285,12 @@ export class LocalTime {
|
|
|
320
285
|
else {
|
|
321
286
|
// year or month
|
|
322
287
|
const lastDay = LocalDate.getMonthLength(d.getFullYear(), d.getMonth() + 1);
|
|
323
|
-
|
|
288
|
+
d.setDate(lastDay);
|
|
324
289
|
}
|
|
325
290
|
}
|
|
326
291
|
}
|
|
327
292
|
}
|
|
328
|
-
|
|
329
|
-
return mutate ? this : new LocalTime(d, this.utcMode);
|
|
293
|
+
return mutate ? this : new LocalTime(d);
|
|
330
294
|
}
|
|
331
295
|
static sort(items, mutate = false, descending = false) {
|
|
332
296
|
const mod = descending ? -1 : 1;
|
|
@@ -395,16 +359,6 @@ export class LocalTime {
|
|
|
395
359
|
return t1 < t2 ? -1 : 1;
|
|
396
360
|
}
|
|
397
361
|
components() {
|
|
398
|
-
if (this.utcMode) {
|
|
399
|
-
return {
|
|
400
|
-
year: this.$date.getUTCFullYear(),
|
|
401
|
-
month: this.$date.getUTCMonth() + 1,
|
|
402
|
-
day: this.$date.getUTCDate(),
|
|
403
|
-
hour: this.$date.getUTCHours(),
|
|
404
|
-
minute: this.$date.getUTCMinutes(),
|
|
405
|
-
second: this.$date.getSeconds(),
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
362
|
return {
|
|
409
363
|
year: this.$date.getFullYear(),
|
|
410
364
|
month: this.$date.getMonth() + 1,
|
|
@@ -427,7 +381,7 @@ export class LocalTime {
|
|
|
427
381
|
return this.$date;
|
|
428
382
|
}
|
|
429
383
|
clone() {
|
|
430
|
-
return new LocalTime(new Date(this.$date)
|
|
384
|
+
return new LocalTime(new Date(this.$date));
|
|
431
385
|
}
|
|
432
386
|
unix() {
|
|
433
387
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
@@ -439,9 +393,6 @@ export class LocalTime {
|
|
|
439
393
|
return Math.floor(this.$date.valueOf() / 1000);
|
|
440
394
|
}
|
|
441
395
|
toLocalDate() {
|
|
442
|
-
if (this.utcMode) {
|
|
443
|
-
return LocalDate.create(this.$date.getUTCFullYear(), this.$date.getUTCMonth() + 1, this.$date.getUTCDate());
|
|
444
|
-
}
|
|
445
396
|
return LocalDate.create(this.$date.getFullYear(), this.$date.getMonth() + 1, this.$date.getDate());
|
|
446
397
|
}
|
|
447
398
|
toPretty(seconds = true) {
|
|
@@ -513,7 +464,7 @@ export class LocalTime {
|
|
|
513
464
|
].join('');
|
|
514
465
|
}
|
|
515
466
|
toString() {
|
|
516
|
-
return
|
|
467
|
+
return this.toISODateTime();
|
|
517
468
|
}
|
|
518
469
|
toJSON() {
|
|
519
470
|
return this.unix();
|
|
@@ -568,29 +519,6 @@ function getWeekYear(date) {
|
|
|
568
519
|
return year - 1;
|
|
569
520
|
}
|
|
570
521
|
}
|
|
571
|
-
// function setWeekYear(
|
|
572
|
-
// date: Date,
|
|
573
|
-
// year: number,
|
|
574
|
-
// ): Date {
|
|
575
|
-
// const diff = differenceInCalendarDays(date, startOfWeekYear(date))
|
|
576
|
-
// const fourthOfJanuary = new Date(0)
|
|
577
|
-
// fourthOfJanuary.setFullYear(year, 0, 4)
|
|
578
|
-
// fourthOfJanuary.setHours(0, 0, 0, 0)
|
|
579
|
-
// date = startOfWeekYear(fourthOfJanuary)
|
|
580
|
-
// date.setDate(date.getDate() + diff)
|
|
581
|
-
// return date
|
|
582
|
-
// }
|
|
583
|
-
// function differenceInCalendarDays(
|
|
584
|
-
// dateLeft: Date,
|
|
585
|
-
// dateRight: Date,
|
|
586
|
-
// ): number {
|
|
587
|
-
// return Math.round((startOfDay(dateLeft).getTime() - startOfDay(dateRight).getTime()) / MILLISECONDS_IN_DAY)
|
|
588
|
-
// }
|
|
589
|
-
// function startOfDay(date: Date, mutate = false): Date {
|
|
590
|
-
// const d = mutate ? date : new Date(date)
|
|
591
|
-
// d.setHours(0, 0, 0, 0)
|
|
592
|
-
// return d
|
|
593
|
-
// }
|
|
594
522
|
// based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/startOfWeek/index.ts
|
|
595
523
|
function startOfWeek(date, mutate = false) {
|
|
596
524
|
const d = mutate ? date : new Date(date);
|
|
@@ -608,3 +536,36 @@ function endOfWeek(date, mutate = false) {
|
|
|
608
536
|
d.setDate(d.getDate() + diff);
|
|
609
537
|
return d;
|
|
610
538
|
}
|
|
539
|
+
function addMonths(d, num, mutate = false) {
|
|
540
|
+
if (!mutate)
|
|
541
|
+
d = new Date(d);
|
|
542
|
+
let day = d.getDate();
|
|
543
|
+
let month = d.getMonth() + 1 + num;
|
|
544
|
+
if (day < 29) {
|
|
545
|
+
d.setMonth(month - 1);
|
|
546
|
+
return d;
|
|
547
|
+
}
|
|
548
|
+
let year = d.getFullYear();
|
|
549
|
+
while (month > 12) {
|
|
550
|
+
year++;
|
|
551
|
+
month -= 12;
|
|
552
|
+
}
|
|
553
|
+
while (month < 1) {
|
|
554
|
+
year--;
|
|
555
|
+
month += 12;
|
|
556
|
+
}
|
|
557
|
+
const monthLen = LocalDate.getMonthLength(year, month);
|
|
558
|
+
if (day > monthLen)
|
|
559
|
+
day = monthLen;
|
|
560
|
+
d.setFullYear(year, month - 1, day);
|
|
561
|
+
return d;
|
|
562
|
+
}
|
|
563
|
+
function differenceInMonths(a, b) {
|
|
564
|
+
if (a.getDate() < b.getDate())
|
|
565
|
+
return -differenceInMonths(b, a);
|
|
566
|
+
const wholeMonthDiff = (b.getFullYear() - a.getFullYear()) * 12 + (b.getMonth() - a.getMonth());
|
|
567
|
+
const anchor = addMonths(a, wholeMonthDiff).getTime();
|
|
568
|
+
const sign = b.getTime() - anchor >= 0 ? 1 : -1;
|
|
569
|
+
const anchor2 = addMonths(a, wholeMonthDiff + sign).getTime();
|
|
570
|
+
return -(wholeMonthDiff + ((b.getTime() - anchor) / (anchor2 - anchor)) * sign);
|
|
571
|
+
}
|
package/package.json
CHANGED
|
@@ -269,7 +269,15 @@ export class LocalDate {
|
|
|
269
269
|
if (unit === 'year') {
|
|
270
270
|
let years = big.$year - small.$year
|
|
271
271
|
|
|
272
|
-
if (
|
|
272
|
+
if (
|
|
273
|
+
big.$month < small.$month ||
|
|
274
|
+
(big.$month === small.$month &&
|
|
275
|
+
big.$day < small.$day &&
|
|
276
|
+
!(
|
|
277
|
+
big.$day === LocalDate.getMonthLength(big.$year, big.$month) &&
|
|
278
|
+
small.$day === LocalDate.getMonthLength(small.$year, small.$month)
|
|
279
|
+
))
|
|
280
|
+
) {
|
|
273
281
|
years--
|
|
274
282
|
}
|
|
275
283
|
|
|
@@ -278,7 +286,12 @@ export class LocalDate {
|
|
|
278
286
|
|
|
279
287
|
if (unit === 'month') {
|
|
280
288
|
let months = (big.$year - small.$year) * 12 + (big.$month - small.$month)
|
|
281
|
-
if (big.$day < small.$day)
|
|
289
|
+
if (big.$day < small.$day) {
|
|
290
|
+
const bigMonthLen = LocalDate.getMonthLength(big.$year, big.$month)
|
|
291
|
+
if (big.$day !== bigMonthLen || small.$day < bigMonthLen) {
|
|
292
|
+
months--
|
|
293
|
+
}
|
|
294
|
+
}
|
|
282
295
|
return months * sign || 0
|
|
283
296
|
}
|
|
284
297
|
|
|
@@ -324,21 +337,37 @@ export class LocalDate {
|
|
|
324
337
|
$year += num
|
|
325
338
|
}
|
|
326
339
|
|
|
340
|
+
// check month overflow
|
|
341
|
+
while ($month > 12) {
|
|
342
|
+
$year += 1
|
|
343
|
+
$month -= 12
|
|
344
|
+
}
|
|
345
|
+
while ($month < 1) {
|
|
346
|
+
$year -= 1
|
|
347
|
+
$month += 12
|
|
348
|
+
}
|
|
349
|
+
|
|
327
350
|
// check day overflow
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
351
|
+
// Applies not only for 'day' unit, but also e.g 2022-05-31 plus 1 month should be 2022-06-30 (not 31!)
|
|
352
|
+
if ($day < 1) {
|
|
353
|
+
while ($day < 1) {
|
|
354
|
+
$month -= 1
|
|
355
|
+
if ($month < 1) {
|
|
356
|
+
$year -= 1
|
|
357
|
+
$month += 12
|
|
358
|
+
}
|
|
336
359
|
|
|
337
|
-
|
|
360
|
+
$day += LocalDate.getMonthLength($year, $month)
|
|
361
|
+
}
|
|
362
|
+
} else {
|
|
363
|
+
let monLen = LocalDate.getMonthLength($year, $month)
|
|
364
|
+
|
|
365
|
+
if (unit !== 'day') {
|
|
366
|
+
if ($day > monLen) {
|
|
367
|
+
// Case of 2022-05-31 plus 1 month should be 2022-06-30, not 31
|
|
368
|
+
$day = monLen
|
|
338
369
|
}
|
|
339
370
|
} else {
|
|
340
|
-
let monLen = LocalDate.getMonthLength($year, $month)
|
|
341
|
-
|
|
342
371
|
while ($day > monLen) {
|
|
343
372
|
$day -= monLen
|
|
344
373
|
$month += 1
|
|
@@ -352,16 +381,6 @@ export class LocalDate {
|
|
|
352
381
|
}
|
|
353
382
|
}
|
|
354
383
|
|
|
355
|
-
// check month overflow
|
|
356
|
-
while ($month > 12) {
|
|
357
|
-
$year += 1
|
|
358
|
-
$month -= 12
|
|
359
|
-
}
|
|
360
|
-
while ($month < 1) {
|
|
361
|
-
$year -= 1
|
|
362
|
-
$month += 12
|
|
363
|
-
}
|
|
364
|
-
|
|
365
384
|
if (mutate) {
|
|
366
385
|
this.$year = $year
|
|
367
386
|
this.$month = $month
|