@naturalcycles/js-lib 14.244.0 → 14.245.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/datetime/dateInterval.d.ts +1 -1
- package/dist/datetime/localDate.d.ts +62 -43
- package/dist/datetime/localDate.js +153 -123
- package/dist/datetime/localTime.d.ts +57 -28
- package/dist/datetime/localTime.js +205 -138
- package/dist/datetime/timeInterval.d.ts +2 -2
- package/dist/datetime/timeInterval.js +2 -2
- package/dist/error/error.util.d.ts +1 -1
- package/dist/index.d.ts +37 -37
- package/dist/index.js +37 -37
- package/dist/json-schema/from-data/generateJsonSchemaFromData.d.ts +1 -1
- package/dist/json-schema/jsonSchemaBuilder.d.ts +1 -1
- package/dist/object/object.util.d.ts +1 -1
- package/dist/time/time.util.js +4 -2
- package/dist/zod/zod.util.d.ts +1 -1
- package/dist-esm/datetime/localDate.js +153 -122
- package/dist-esm/datetime/localTime.js +205 -137
- package/dist-esm/datetime/timeInterval.js +2 -2
- package/dist-esm/decorators/logMethod.decorator.js +1 -1
- package/dist-esm/index.js +37 -37
- package/dist-esm/json-schema/jsonSchemaBuilder.js +1 -1
- package/dist-esm/time/time.util.js +4 -2
- package/package.json +1 -1
- package/src/datetime/dateInterval.ts +1 -1
- package/src/datetime/localDate.ts +157 -133
- package/src/datetime/localTime.ts +204 -149
- package/src/datetime/timeInterval.ts +4 -4
- package/src/decorators/logMethod.decorator.ts +1 -1
- package/src/define.ts +1 -1
- package/src/error/error.util.ts +3 -3
- package/src/http/fetcher.ts +1 -1
- package/src/index.ts +37 -37
- package/src/json-schema/from-data/generateJsonSchemaFromData.ts +1 -1
- package/src/json-schema/jsonSchemaBuilder.ts +2 -2
- package/src/object/object.util.ts +1 -1
- package/src/time/time.util.ts +4 -1
- package/src/zod/zod.util.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Inclusiveness } from '../types';
|
|
2
|
-
import { LocalDateInput, LocalDateUnit
|
|
2
|
+
import { LocalDate, LocalDateInput, LocalDateUnit } from './localDate';
|
|
3
3
|
export type DateIntervalConfig = DateInterval | DateIntervalString;
|
|
4
4
|
export type DateIntervalString = string;
|
|
5
5
|
/**
|
|
@@ -146,6 +146,28 @@ export declare class LocalDate {
|
|
|
146
146
|
format(fmt: Intl.DateTimeFormat | LocalDateFormatter): string;
|
|
147
147
|
}
|
|
148
148
|
declare class LocalDateFactory {
|
|
149
|
+
/**
|
|
150
|
+
* Creates a LocalDate from the input, unless it's falsy - then returns undefined.
|
|
151
|
+
*
|
|
152
|
+
* Similar to `localDate.orToday`, but that will instead return Today on falsy input.
|
|
153
|
+
*/
|
|
154
|
+
orUndefined(d: LocalDateInputNullable): LocalDate | undefined;
|
|
155
|
+
/**
|
|
156
|
+
* Creates a LocalDate from the input, unless it's falsy - then returns localDate.today.
|
|
157
|
+
*/
|
|
158
|
+
orToday(d: LocalDateInputNullable): LocalDate;
|
|
159
|
+
/**
|
|
160
|
+
* Creates LocalDate that represents `today` (in local timezone).
|
|
161
|
+
*/
|
|
162
|
+
today(): LocalDate;
|
|
163
|
+
/**
|
|
164
|
+
* Creates LocalDate that represents `today` in UTC.
|
|
165
|
+
*/
|
|
166
|
+
todayInUTC(): LocalDate;
|
|
167
|
+
/**
|
|
168
|
+
Convenience function to return current today's IsoDateString representation, e.g `2024-06-21`
|
|
169
|
+
*/
|
|
170
|
+
todayString(): IsoDateString;
|
|
149
171
|
/**
|
|
150
172
|
* Create LocalDate from LocalDateInput.
|
|
151
173
|
* Input can already be a LocalDate - it is returned as-is in that case.
|
|
@@ -155,54 +177,62 @@ declare class LocalDateFactory {
|
|
|
155
177
|
*
|
|
156
178
|
* Will throw if it fails to parse/construct LocalDate.
|
|
157
179
|
*/
|
|
158
|
-
|
|
180
|
+
fromInput(input: LocalDateInput): LocalDate;
|
|
181
|
+
/**
|
|
182
|
+
* Returns true if input is valid to create LocalDate.
|
|
183
|
+
*/
|
|
184
|
+
isValid(input: LocalDateInputNullable): boolean;
|
|
185
|
+
/**
|
|
186
|
+
* Returns true if isoString is a valid iso8601 string like `yyyy-mm-dd`.
|
|
187
|
+
*/
|
|
188
|
+
isValidString(isoString: string | undefined | null): boolean;
|
|
189
|
+
/**
|
|
190
|
+
* Tries to convert/parse the input into LocalDate.
|
|
191
|
+
* Uses LOOSE parsing.
|
|
192
|
+
* If invalid - doesn't throw, but returns undefined instead.
|
|
193
|
+
*/
|
|
194
|
+
try(input: LocalDateInputNullable): LocalDate | undefined;
|
|
159
195
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
196
|
+
* Performs STRICT parsing.
|
|
197
|
+
* Only allows IsoDateString input, nothing else.
|
|
162
198
|
*/
|
|
163
|
-
|
|
164
|
-
fromString(s: string): LocalDate;
|
|
165
|
-
fromStringOrNull(s: string | undefined | null): LocalDate | null;
|
|
199
|
+
fromIsoDateString(s: IsoDateString): LocalDate;
|
|
166
200
|
/**
|
|
167
201
|
* Parses "compact iso8601 format", e.g `19840621` into LocalDate.
|
|
168
202
|
* Throws if it fails to do so.
|
|
169
203
|
*/
|
|
170
204
|
fromCompactString(s: string): LocalDate;
|
|
171
205
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Constructs LocalDate from Date.
|
|
178
|
-
* Takes Date's year/month/day components in UTC, using getUTCFullYear, getUTCMonth, getUTCDate.
|
|
206
|
+
* Performs LOOSE parsing.
|
|
207
|
+
* Tries to coerce imprefect/incorrect string input into IsoDateString.
|
|
208
|
+
* Use with caution.
|
|
209
|
+
* Allows to input IsoDateTimeString, will drop the Time part of it.
|
|
179
210
|
*/
|
|
180
|
-
|
|
211
|
+
parse(s: string): LocalDate;
|
|
181
212
|
/**
|
|
182
|
-
*
|
|
213
|
+
* Throws if it fails to parse the input string via Regex and YMD validation.
|
|
183
214
|
*/
|
|
184
|
-
|
|
185
|
-
fromDateObject(o: DateObject): LocalDate;
|
|
186
|
-
private assertNotNull;
|
|
187
|
-
getYearLength(year: number): number;
|
|
188
|
-
getMonthLength(year: number, month: number): number;
|
|
189
|
-
isLeapYear(year: number): boolean;
|
|
215
|
+
private parseToLocalDate;
|
|
190
216
|
/**
|
|
191
|
-
*
|
|
217
|
+
* Tries to parse the input string, returns undefined if input is invalid.
|
|
192
218
|
*/
|
|
193
|
-
|
|
219
|
+
private parseToLocalDateOrUndefined;
|
|
194
220
|
/**
|
|
195
|
-
*
|
|
221
|
+
* Throws on invalid value.
|
|
196
222
|
*/
|
|
197
|
-
|
|
223
|
+
private validateDateObject;
|
|
224
|
+
isDateObjectValid({ year, month, day }: DateObject): boolean;
|
|
198
225
|
/**
|
|
199
|
-
*
|
|
226
|
+
* Constructs LocalDate from Date.
|
|
227
|
+
* Takes Date as-is, in its timezone - local or UTC.
|
|
200
228
|
*/
|
|
201
|
-
|
|
229
|
+
fromDate(d: Date): LocalDate;
|
|
202
230
|
/**
|
|
203
|
-
*
|
|
231
|
+
* Constructs LocalDate from Date.
|
|
232
|
+
* Takes Date's year/month/day components in UTC, using getUTCFullYear, getUTCMonth, getUTCDate.
|
|
204
233
|
*/
|
|
205
|
-
|
|
234
|
+
fromDateInUTC(d: Date): LocalDate;
|
|
235
|
+
fromDateObject(o: DateObject): LocalDate;
|
|
206
236
|
/**
|
|
207
237
|
* Sorts an array of LocalDates in `dir` order (ascending by default).
|
|
208
238
|
*/
|
|
@@ -235,23 +265,12 @@ declare class LocalDateFactory {
|
|
|
235
265
|
* By default, min is included, max is excluded.
|
|
236
266
|
*/
|
|
237
267
|
rangeIterable(min: LocalDateInput, max: LocalDateInput, incl?: Inclusiveness, step?: number, stepUnit?: LocalDateUnit): Iterable2<LocalDate>;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
* Similar to `localDate.orToday`, but that will instead return Today on falsy input.
|
|
242
|
-
*/
|
|
243
|
-
orUndefined(d: LocalDateInputNullable): LocalDate | undefined;
|
|
244
|
-
/**
|
|
245
|
-
* Creates a LocalDate from the input, unless it's falsy - then returns localDate.today.
|
|
246
|
-
*/
|
|
247
|
-
orToday(d: LocalDateInputNullable): LocalDate;
|
|
268
|
+
getYearLength(year: number): number;
|
|
269
|
+
getMonthLength(year: number, month: number): number;
|
|
270
|
+
isLeapYear(year: number): boolean;
|
|
248
271
|
}
|
|
249
272
|
interface LocalDateFn extends LocalDateFactory {
|
|
250
273
|
(d: LocalDateInput): LocalDate;
|
|
251
274
|
}
|
|
252
275
|
export declare const localDate: LocalDateFn;
|
|
253
|
-
/**
|
|
254
|
-
Convenience function to return current today's IsoDateString representation, e.g `2024-06-21`
|
|
255
|
-
*/
|
|
256
|
-
export declare function todayString(): IsoDateString;
|
|
257
276
|
export {};
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.localDate = exports.LocalDate = void 0;
|
|
4
|
-
exports.todayString = todayString;
|
|
5
4
|
const assert_1 = require("../error/assert");
|
|
6
5
|
const is_util_1 = require("../is.util");
|
|
7
6
|
const iterable2_1 = require("../iter/iterable2");
|
|
8
7
|
const localTime_1 = require("./localTime");
|
|
9
8
|
const MDAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Regex is open-ended (no $ at the end) to support e.g Date+Time string to be parsed (time part will be dropped)
|
|
11
|
+
*/
|
|
12
|
+
const DATE_REGEX_LOOSE = /^(\d\d\d\d)-(\d\d)-(\d\d)/;
|
|
13
|
+
/**
|
|
14
|
+
* Strict version.
|
|
15
|
+
*/
|
|
16
|
+
const DATE_REGEX_STRICT = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
17
|
+
const COMPACT_DATE_REGEX = /^(\d\d\d\d)(\d\d)(\d\d)$/;
|
|
12
18
|
/**
|
|
13
19
|
* LocalDate represents a date without time.
|
|
14
20
|
* It is timezone-independent.
|
|
@@ -48,7 +54,7 @@ class LocalDate {
|
|
|
48
54
|
return (this.toDate().getDay() || 7);
|
|
49
55
|
}
|
|
50
56
|
isSame(d) {
|
|
51
|
-
d = exports.localDate.
|
|
57
|
+
d = exports.localDate.fromInput(d);
|
|
52
58
|
return this.day === d.day && this.month === d.month && this.year === d.year;
|
|
53
59
|
}
|
|
54
60
|
isBefore(d, inclusive = false) {
|
|
@@ -85,13 +91,13 @@ class LocalDate {
|
|
|
85
91
|
* Third argument allows to override "today".
|
|
86
92
|
*/
|
|
87
93
|
isOlderThan(n, unit, today) {
|
|
88
|
-
return this.isBefore(exports.localDate.
|
|
94
|
+
return this.isBefore(exports.localDate.fromInput(today || new Date()).plus(-n, unit));
|
|
89
95
|
}
|
|
90
96
|
/**
|
|
91
97
|
* Checks if this localDate is same or older (<=) than "today" by X units.
|
|
92
98
|
*/
|
|
93
99
|
isSameOrOlderThan(n, unit, today) {
|
|
94
|
-
return this.isSameOrBefore(exports.localDate.
|
|
100
|
+
return this.isSameOrBefore(exports.localDate.fromInput(today || new Date()).plus(-n, unit));
|
|
95
101
|
}
|
|
96
102
|
/**
|
|
97
103
|
* Checks if this localDate is younger (>) than "today" by X units.
|
|
@@ -103,13 +109,13 @@ class LocalDate {
|
|
|
103
109
|
* Third argument allows to override "today".
|
|
104
110
|
*/
|
|
105
111
|
isYoungerThan(n, unit, today) {
|
|
106
|
-
return this.isAfter(exports.localDate.
|
|
112
|
+
return this.isAfter(exports.localDate.fromInput(today || new Date()).plus(-n, unit));
|
|
107
113
|
}
|
|
108
114
|
/**
|
|
109
115
|
* Checks if this localDate is same or younger (>=) than "today" by X units.
|
|
110
116
|
*/
|
|
111
117
|
isSameOrYoungerThan(n, unit, today) {
|
|
112
|
-
return this.isSameOrAfter(exports.localDate.
|
|
118
|
+
return this.isSameOrAfter(exports.localDate.fromInput(today || new Date()).plus(-n, unit));
|
|
113
119
|
}
|
|
114
120
|
getAgeInYears(today) {
|
|
115
121
|
return this.getAgeIn('year', today);
|
|
@@ -121,7 +127,7 @@ class LocalDate {
|
|
|
121
127
|
return this.getAgeIn('day', today);
|
|
122
128
|
}
|
|
123
129
|
getAgeIn(unit, today) {
|
|
124
|
-
return exports.localDate.
|
|
130
|
+
return exports.localDate.fromInput(today || new Date()).diff(this, unit);
|
|
125
131
|
}
|
|
126
132
|
/**
|
|
127
133
|
* Returns 1 if this > d
|
|
@@ -129,7 +135,7 @@ class LocalDate {
|
|
|
129
135
|
* returns -1 if this < d
|
|
130
136
|
*/
|
|
131
137
|
compare(d) {
|
|
132
|
-
d = exports.localDate.
|
|
138
|
+
d = exports.localDate.fromInput(d);
|
|
133
139
|
if (this.year < d.year)
|
|
134
140
|
return -1;
|
|
135
141
|
if (this.year > d.year)
|
|
@@ -156,7 +162,7 @@ class LocalDate {
|
|
|
156
162
|
* a.diff(b) means "a minus b"
|
|
157
163
|
*/
|
|
158
164
|
diff(d, unit) {
|
|
159
|
-
d = exports.localDate.
|
|
165
|
+
d = exports.localDate.fromInput(d);
|
|
160
166
|
const sign = this.compare(d);
|
|
161
167
|
if (!sign)
|
|
162
168
|
return 0;
|
|
@@ -307,8 +313,9 @@ class LocalDate {
|
|
|
307
313
|
endOf(unit) {
|
|
308
314
|
if (unit === 'day')
|
|
309
315
|
return this;
|
|
310
|
-
if (unit === 'month')
|
|
316
|
+
if (unit === 'month') {
|
|
311
317
|
return new LocalDate(this.year, this.month, exports.localDate.getMonthLength(this.year, this.month));
|
|
318
|
+
}
|
|
312
319
|
// year
|
|
313
320
|
return new LocalDate(this.year, 12, 31);
|
|
314
321
|
}
|
|
@@ -419,6 +426,38 @@ class LocalDate {
|
|
|
419
426
|
}
|
|
420
427
|
exports.LocalDate = LocalDate;
|
|
421
428
|
class LocalDateFactory {
|
|
429
|
+
/**
|
|
430
|
+
* Creates a LocalDate from the input, unless it's falsy - then returns undefined.
|
|
431
|
+
*
|
|
432
|
+
* Similar to `localDate.orToday`, but that will instead return Today on falsy input.
|
|
433
|
+
*/
|
|
434
|
+
orUndefined(d) {
|
|
435
|
+
return d ? this.fromInput(d) : undefined;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Creates a LocalDate from the input, unless it's falsy - then returns localDate.today.
|
|
439
|
+
*/
|
|
440
|
+
orToday(d) {
|
|
441
|
+
return d ? this.fromInput(d) : this.today();
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Creates LocalDate that represents `today` (in local timezone).
|
|
445
|
+
*/
|
|
446
|
+
today() {
|
|
447
|
+
return this.fromDate(new Date());
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Creates LocalDate that represents `today` in UTC.
|
|
451
|
+
*/
|
|
452
|
+
todayInUTC() {
|
|
453
|
+
return this.fromDateInUTC(new Date());
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
Convenience function to return current today's IsoDateString representation, e.g `2024-06-21`
|
|
457
|
+
*/
|
|
458
|
+
todayString() {
|
|
459
|
+
return this.fromDate(new Date()).toISODate();
|
|
460
|
+
}
|
|
422
461
|
/**
|
|
423
462
|
* Create LocalDate from LocalDateInput.
|
|
424
463
|
* Input can already be a LocalDate - it is returned as-is in that case.
|
|
@@ -428,125 +467,125 @@ class LocalDateFactory {
|
|
|
428
467
|
*
|
|
429
468
|
* Will throw if it fails to parse/construct LocalDate.
|
|
430
469
|
*/
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
470
|
+
fromInput(input) {
|
|
471
|
+
if (input instanceof LocalDate)
|
|
472
|
+
return input;
|
|
473
|
+
if (input instanceof Date) {
|
|
474
|
+
return this.fromDate(input);
|
|
475
|
+
}
|
|
476
|
+
// It means it's a string
|
|
477
|
+
return this.fromIsoDateString(input);
|
|
435
478
|
}
|
|
436
479
|
/**
|
|
437
|
-
*
|
|
438
|
-
* Does not throw (returns null instead).
|
|
480
|
+
* Returns true if input is valid to create LocalDate.
|
|
439
481
|
*/
|
|
440
|
-
|
|
441
|
-
if (!
|
|
442
|
-
return
|
|
443
|
-
if (
|
|
444
|
-
return
|
|
445
|
-
if (
|
|
446
|
-
return
|
|
447
|
-
|
|
448
|
-
if (typeof d === 'string') {
|
|
449
|
-
return this.fromStringOrNull(d);
|
|
450
|
-
}
|
|
451
|
-
return null;
|
|
452
|
-
}
|
|
453
|
-
fromString(s) {
|
|
454
|
-
const ld = this.fromStringOrNull(s);
|
|
455
|
-
this.assertNotNull(ld, s);
|
|
456
|
-
return ld;
|
|
482
|
+
isValid(input) {
|
|
483
|
+
if (!input)
|
|
484
|
+
return false;
|
|
485
|
+
if (input instanceof LocalDate)
|
|
486
|
+
return true;
|
|
487
|
+
if (input instanceof Date)
|
|
488
|
+
return !isNaN(input.getDate());
|
|
489
|
+
return this.isValidString(input);
|
|
457
490
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
491
|
+
/**
|
|
492
|
+
* Returns true if isoString is a valid iso8601 string like `yyyy-mm-dd`.
|
|
493
|
+
*/
|
|
494
|
+
isValidString(isoString) {
|
|
495
|
+
return !!this.parseToLocalDateOrUndefined(DATE_REGEX_STRICT, isoString);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Tries to convert/parse the input into LocalDate.
|
|
499
|
+
* Uses LOOSE parsing.
|
|
500
|
+
* If invalid - doesn't throw, but returns undefined instead.
|
|
501
|
+
*/
|
|
502
|
+
try(input) {
|
|
503
|
+
if (!input)
|
|
504
|
+
return;
|
|
505
|
+
if (input instanceof LocalDate)
|
|
506
|
+
return input;
|
|
507
|
+
if (input instanceof Date) {
|
|
508
|
+
if (isNaN(input.getDate()))
|
|
509
|
+
return;
|
|
510
|
+
return new LocalDate(input.getFullYear(), input.getMonth() + 1, input.getDate());
|
|
475
511
|
}
|
|
476
|
-
return
|
|
512
|
+
return this.parseToLocalDateOrUndefined(DATE_REGEX_LOOSE, input);
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Performs STRICT parsing.
|
|
516
|
+
* Only allows IsoDateString input, nothing else.
|
|
517
|
+
*/
|
|
518
|
+
fromIsoDateString(s) {
|
|
519
|
+
return this.parseToLocalDate(DATE_REGEX_STRICT, s);
|
|
477
520
|
}
|
|
478
521
|
/**
|
|
479
522
|
* Parses "compact iso8601 format", e.g `19840621` into LocalDate.
|
|
480
523
|
* Throws if it fails to do so.
|
|
481
524
|
*/
|
|
482
525
|
fromCompactString(s) {
|
|
483
|
-
|
|
484
|
-
(0, assert_1._assert)(day && month && year, `Cannot parse compact string "${s}" into LocalDate`);
|
|
485
|
-
return new LocalDate(year, month, day);
|
|
526
|
+
return this.parseToLocalDate(COMPACT_DATE_REGEX, s);
|
|
486
527
|
}
|
|
487
528
|
/**
|
|
488
|
-
*
|
|
489
|
-
*
|
|
529
|
+
* Performs LOOSE parsing.
|
|
530
|
+
* Tries to coerce imprefect/incorrect string input into IsoDateString.
|
|
531
|
+
* Use with caution.
|
|
532
|
+
* Allows to input IsoDateTimeString, will drop the Time part of it.
|
|
490
533
|
*/
|
|
491
|
-
|
|
492
|
-
return
|
|
534
|
+
parse(s) {
|
|
535
|
+
return this.parseToLocalDate(DATE_REGEX_LOOSE, String(s));
|
|
493
536
|
}
|
|
494
537
|
/**
|
|
495
|
-
*
|
|
496
|
-
* Takes Date's year/month/day components in UTC, using getUTCFullYear, getUTCMonth, getUTCDate.
|
|
538
|
+
* Throws if it fails to parse the input string via Regex and YMD validation.
|
|
497
539
|
*/
|
|
498
|
-
|
|
499
|
-
|
|
540
|
+
parseToLocalDate(regex, s) {
|
|
541
|
+
const ld = this.parseToLocalDateOrUndefined(regex, s);
|
|
542
|
+
(0, assert_1._assert)(ld, `Cannot parse "${s}" into LocalDate`);
|
|
543
|
+
return ld;
|
|
500
544
|
}
|
|
501
545
|
/**
|
|
502
|
-
*
|
|
546
|
+
* Tries to parse the input string, returns undefined if input is invalid.
|
|
503
547
|
*/
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
548
|
+
parseToLocalDateOrUndefined(regex, s) {
|
|
549
|
+
if (!s || typeof s !== 'string')
|
|
550
|
+
return;
|
|
551
|
+
const m = regex.exec(s);
|
|
552
|
+
if (!m)
|
|
553
|
+
return;
|
|
554
|
+
const year = Number(m[1]);
|
|
555
|
+
const month = Number(m[2]);
|
|
556
|
+
const day = Number(m[3]);
|
|
557
|
+
if (!this.isDateObjectValid({ year, month, day }))
|
|
558
|
+
return;
|
|
509
559
|
return new LocalDate(year, month, day);
|
|
510
560
|
}
|
|
511
|
-
assertNotNull(ld, input) {
|
|
512
|
-
(0, assert_1._assert)(ld !== null, `Cannot parse "${input}" into LocalDate`, {
|
|
513
|
-
input,
|
|
514
|
-
});
|
|
515
|
-
}
|
|
516
|
-
getYearLength(year) {
|
|
517
|
-
return this.isLeapYear(year) ? 366 : 365;
|
|
518
|
-
}
|
|
519
|
-
getMonthLength(year, month) {
|
|
520
|
-
if (month === 2)
|
|
521
|
-
return this.isLeapYear(year) ? 29 : 28;
|
|
522
|
-
return MDAYS[month];
|
|
523
|
-
}
|
|
524
|
-
isLeapYear(year) {
|
|
525
|
-
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
526
|
-
}
|
|
527
561
|
/**
|
|
528
|
-
*
|
|
562
|
+
* Throws on invalid value.
|
|
529
563
|
*/
|
|
530
|
-
|
|
531
|
-
|
|
564
|
+
validateDateObject(o) {
|
|
565
|
+
(0, assert_1._assert)(this.isDateObjectValid(o), `Cannot construct LocalDate from: ${o.year}-${o.month}-${o.day}`);
|
|
532
566
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
*/
|
|
536
|
-
isValidString(isoString) {
|
|
537
|
-
return this.fromStringOrNull(isoString) !== null;
|
|
567
|
+
isDateObjectValid({ year, month, day }) {
|
|
568
|
+
return (!!year && month >= 1 && month <= 12 && day >= 1 && day <= this.getMonthLength(year, month));
|
|
538
569
|
}
|
|
539
570
|
/**
|
|
540
|
-
*
|
|
571
|
+
* Constructs LocalDate from Date.
|
|
572
|
+
* Takes Date as-is, in its timezone - local or UTC.
|
|
541
573
|
*/
|
|
542
|
-
|
|
543
|
-
|
|
574
|
+
fromDate(d) {
|
|
575
|
+
(0, assert_1._assert)(!isNaN(d.getDate()), `localDate.fromDate is called on Date object that is invalid`);
|
|
576
|
+
return new LocalDate(d.getFullYear(), d.getMonth() + 1, d.getDate());
|
|
544
577
|
}
|
|
545
578
|
/**
|
|
546
|
-
*
|
|
579
|
+
* Constructs LocalDate from Date.
|
|
580
|
+
* Takes Date's year/month/day components in UTC, using getUTCFullYear, getUTCMonth, getUTCDate.
|
|
547
581
|
*/
|
|
548
|
-
|
|
549
|
-
|
|
582
|
+
fromDateInUTC(d) {
|
|
583
|
+
(0, assert_1._assert)(!isNaN(d.getDate()), `localDate.fromDateInUTC is called on Date object that is invalid`);
|
|
584
|
+
return new LocalDate(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate());
|
|
585
|
+
}
|
|
586
|
+
fromDateObject(o) {
|
|
587
|
+
this.validateDateObject(o);
|
|
588
|
+
return new LocalDate(o.year, o.month, o.day);
|
|
550
589
|
}
|
|
551
590
|
/**
|
|
552
591
|
* Sorts an array of LocalDates in `dir` order (ascending by default).
|
|
@@ -569,7 +608,7 @@ class LocalDateFactory {
|
|
|
569
608
|
const items2 = items.filter(is_util_1._isTruthy);
|
|
570
609
|
(0, assert_1._assert)(items2.length, 'localDate.min called on empty array');
|
|
571
610
|
return items2
|
|
572
|
-
.map(i => this.
|
|
611
|
+
.map(i => this.fromInput(i))
|
|
573
612
|
.reduce((min, item) => (min.isSameOrBefore(item) ? min : item));
|
|
574
613
|
}
|
|
575
614
|
/**
|
|
@@ -586,7 +625,7 @@ class LocalDateFactory {
|
|
|
586
625
|
const items2 = items.filter(is_util_1._isTruthy);
|
|
587
626
|
(0, assert_1._assert)(items2.length, 'localDate.max called on empty array');
|
|
588
627
|
return items2
|
|
589
|
-
.map(i => this.
|
|
628
|
+
.map(i => this.fromInput(i))
|
|
590
629
|
.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
|
|
591
630
|
}
|
|
592
631
|
/**
|
|
@@ -605,8 +644,8 @@ class LocalDateFactory {
|
|
|
605
644
|
step *= 7;
|
|
606
645
|
stepUnit = 'day';
|
|
607
646
|
}
|
|
608
|
-
const $min = this.
|
|
609
|
-
const $max = this.
|
|
647
|
+
const $min = this.fromInput(min).startOf(stepUnit);
|
|
648
|
+
const $max = this.fromInput(max).startOf(stepUnit);
|
|
610
649
|
let value = $min;
|
|
611
650
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
612
651
|
if (value.isAfter($min, incl[0] === '[')) {
|
|
@@ -627,29 +666,20 @@ class LocalDateFactory {
|
|
|
627
666
|
},
|
|
628
667
|
});
|
|
629
668
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
*
|
|
633
|
-
* Similar to `localDate.orToday`, but that will instead return Today on falsy input.
|
|
634
|
-
*/
|
|
635
|
-
orUndefined(d) {
|
|
636
|
-
return d ? this.from(d) : undefined;
|
|
669
|
+
getYearLength(year) {
|
|
670
|
+
return this.isLeapYear(year) ? 366 : 365;
|
|
637
671
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
672
|
+
getMonthLength(year, month) {
|
|
673
|
+
if (month === 2)
|
|
674
|
+
return this.isLeapYear(year) ? 29 : 28;
|
|
675
|
+
return MDAYS[month];
|
|
676
|
+
}
|
|
677
|
+
isLeapYear(year) {
|
|
678
|
+
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
643
679
|
}
|
|
644
680
|
}
|
|
645
681
|
const localDateFactory = new LocalDateFactory();
|
|
646
|
-
exports.localDate = localDateFactory.
|
|
682
|
+
exports.localDate = localDateFactory.fromInput.bind(localDateFactory);
|
|
647
683
|
// The line below is the blackest of black magic I have ever written in 2024.
|
|
648
684
|
// And probably 2023 as well.
|
|
649
685
|
Object.setPrototypeOf(exports.localDate, localDateFactory);
|
|
650
|
-
/**
|
|
651
|
-
Convenience function to return current today's IsoDateString representation, e.g `2024-06-21`
|
|
652
|
-
*/
|
|
653
|
-
function todayString() {
|
|
654
|
-
return exports.localDate.fromDate(new Date()).toISODate();
|
|
655
|
-
}
|