@naturalcycles/js-lib 14.88.0 → 14.89.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.
@@ -0,0 +1,285 @@
1
+ import { _assert } from '../error/assert';
2
+ import { Sequence } from '../seq/seq';
3
+ import { END } from '../types';
4
+ const m31 = new Set([1, 3, 5, 7, 8, 10, 12]);
5
+ /**
6
+ * @experimental
7
+ */
8
+ export class LocalDate {
9
+ constructor(year, month, day) {
10
+ this.year = year;
11
+ this.month = month;
12
+ this.day = day;
13
+ }
14
+ static create(year, month, day) {
15
+ return new LocalDate(year, month, day);
16
+ }
17
+ /**
18
+ * Parses input String into LocalDate.
19
+ * Input can already be a LocalDate - it is returned as-is in that case.
20
+ */
21
+ static of(d) {
22
+ if (d instanceof LocalDate)
23
+ return d;
24
+ const [year, month, day] = d.slice(0, 10).split('-').map(Number);
25
+ if (!day || !month || (!year && year !== 0)) {
26
+ throw new Error(`Cannot parse "${d}" into LocalDate`);
27
+ }
28
+ return new LocalDate(year, month, day);
29
+ }
30
+ static parseCompact(d) {
31
+ const [year, month, day] = [d.slice(0, 4), d.slice(4, 2), d.slice(6, 2)].map(Number);
32
+ if (!day || !month || (!year && year !== 0)) {
33
+ throw new Error(`Cannot parse "${d}" into LocalDate`);
34
+ }
35
+ return new LocalDate(year, month, day);
36
+ }
37
+ static fromDate(d) {
38
+ return new LocalDate(d.getFullYear(), d.getMonth() + 1, d.getDate());
39
+ }
40
+ static today() {
41
+ return this.fromDate(new Date());
42
+ }
43
+ static sort(items, mutate = false, descending = false) {
44
+ const mod = descending ? -1 : 1;
45
+ return (mutate ? items : [...items]).sort((a, b) => a.cmp(b) * mod);
46
+ }
47
+ static earliestOrUndefined(items) {
48
+ return items.length ? LocalDate.earliest(items) : undefined;
49
+ }
50
+ static earliest(items) {
51
+ _assert(items.length, 'LocalDate.earliest called on empty array');
52
+ return items.reduce((min, item) => (min.isSameOrBefore(item) ? min : item));
53
+ }
54
+ static latestOrUndefined(items) {
55
+ return items.length ? LocalDate.latest(items) : undefined;
56
+ }
57
+ static latest(items) {
58
+ _assert(items.length, 'LocalDate.latest called on empty array');
59
+ return items.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
60
+ }
61
+ static range(minIncl, maxExcl, step = 1, stepUnit = 'day') {
62
+ const days = [];
63
+ let current = LocalDate.of(minIncl).startOf(stepUnit);
64
+ const max = LocalDate.of(maxExcl).startOf(stepUnit);
65
+ do {
66
+ days.push(current);
67
+ current = current.add(step, stepUnit);
68
+ } while (current.isBefore(max));
69
+ return days;
70
+ }
71
+ static rangeSeq(minIncl, maxExcl, step = 1, stepUnit = 'day') {
72
+ const min = LocalDate.of(minIncl).startOf(stepUnit);
73
+ const max = LocalDate.of(maxExcl).startOf(stepUnit);
74
+ return Sequence.create(min, d => {
75
+ const next = d.add(step, stepUnit);
76
+ return next.isAfter(max) ? END : next;
77
+ });
78
+ }
79
+ static rangeString(minIncl, maxExcl, step = 1, stepUnit = 'day') {
80
+ return LocalDate.range(minIncl, maxExcl, step, stepUnit).map(ld => ld.toString());
81
+ }
82
+ static rangeIncl(minIncl, maxIncl, step = 1, stepUnit = 'day') {
83
+ return LocalDate.range(minIncl, LocalDate.of(maxIncl).add(1, stepUnit), step, stepUnit);
84
+ }
85
+ static rangeInclString(minIncl, maxIncl, step = 1, stepUnit = 'day') {
86
+ return LocalDate.range(minIncl, LocalDate.of(maxIncl).add(1, stepUnit), step, stepUnit).map(ld => ld.toString());
87
+ }
88
+ isSame(d) {
89
+ d = LocalDate.of(d);
90
+ return this.day === d.day && this.month === d.month && this.year === d.year;
91
+ }
92
+ isBefore(d) {
93
+ return this.cmp(d) === -1;
94
+ }
95
+ isSameOrBefore(d) {
96
+ return this.cmp(d) <= 0;
97
+ }
98
+ isAfter(d) {
99
+ return this.cmp(d) === 1;
100
+ }
101
+ isSameOrAfter(d) {
102
+ return this.cmp(d) >= 0;
103
+ }
104
+ /**
105
+ * Returns 1 if this > d
106
+ * returns 0 if they are equal
107
+ * returns -1 if this < d
108
+ */
109
+ cmp(d) {
110
+ d = LocalDate.of(d);
111
+ if (this.year < d.year)
112
+ return -1;
113
+ if (this.year > d.year)
114
+ return 1;
115
+ if (this.month < d.month)
116
+ return -1;
117
+ if (this.month > d.month)
118
+ return 1;
119
+ if (this.day < d.day)
120
+ return -1;
121
+ if (this.day > d.day)
122
+ return 1;
123
+ return 0;
124
+ }
125
+ /**
126
+ * Same as Math.abs( diff )
127
+ */
128
+ absDiff(d, unit) {
129
+ return Math.abs(this.diff(d, unit));
130
+ }
131
+ /**
132
+ * Returns the number of **full** units difference (aka `Math.ceil`).
133
+ *
134
+ * a.diff(b) means "a minus b"
135
+ */
136
+ diff(d, unit) {
137
+ d = LocalDate.of(d);
138
+ if (unit === 'year') {
139
+ return this.year - d.year;
140
+ }
141
+ if (unit === 'month') {
142
+ return (this.year - d.year) * 12 + (this.month - d.month);
143
+ }
144
+ // unit is 'day'
145
+ let days = this.day - d.day;
146
+ if (d.year < this.year) {
147
+ for (let year = d.year; year < this.year; year++) {
148
+ days += this.getYearDays(year);
149
+ }
150
+ }
151
+ else if (this.year < d.year) {
152
+ for (let year = this.year; year < d.year; year++) {
153
+ days -= this.getYearDays(year);
154
+ }
155
+ }
156
+ if (d.month < this.month) {
157
+ for (let month = d.month; month < this.month; month++) {
158
+ days += this.getMonthLen(this.year, month);
159
+ }
160
+ }
161
+ else if (this.month < d.month) {
162
+ for (let month = this.month; month < d.month; month++) {
163
+ days -= this.getMonthLen(d.year, month);
164
+ }
165
+ }
166
+ return days;
167
+ }
168
+ add(num, unit, mutate = false) {
169
+ let { day, month, year } = this;
170
+ if (unit === 'day') {
171
+ day += num;
172
+ }
173
+ else if (unit === 'month') {
174
+ month += num;
175
+ }
176
+ else if (unit === 'year') {
177
+ year += num;
178
+ }
179
+ // check day overflow
180
+ let monLen = this.getMonthLen(year, month);
181
+ while (day > monLen) {
182
+ day -= monLen;
183
+ month += 1;
184
+ if (month > 12) {
185
+ year += 1;
186
+ month -= 12;
187
+ }
188
+ monLen = this.getMonthLen(year, month);
189
+ }
190
+ while (day < 1) {
191
+ day += monLen;
192
+ month -= 1;
193
+ if (month < 1) {
194
+ year -= 1;
195
+ month += 12;
196
+ }
197
+ monLen = this.getMonthLen(year, month);
198
+ }
199
+ // check month overflow
200
+ while (month > 12) {
201
+ year += 1;
202
+ month -= 12;
203
+ }
204
+ while (month < 1) {
205
+ year -= 1;
206
+ month += 12;
207
+ }
208
+ if (mutate) {
209
+ this.year = year;
210
+ this.month = month;
211
+ this.day = day;
212
+ return this;
213
+ }
214
+ return new LocalDate(year, month, day);
215
+ }
216
+ subtract(num, unit, mutate = false) {
217
+ return this.add(-num, unit, mutate);
218
+ }
219
+ startOf(unit) {
220
+ if (unit === 'day')
221
+ return this;
222
+ if (unit === 'month')
223
+ return LocalDate.create(this.year, this.month, 1);
224
+ // year
225
+ return LocalDate.create(this.year, 1, 1);
226
+ }
227
+ endOf(unit) {
228
+ if (unit === 'day')
229
+ return this;
230
+ if (unit === 'month')
231
+ return LocalDate.create(this.year, this.month, this.getMonthLen(this.year, this.month));
232
+ // year
233
+ return LocalDate.create(this.year, 12, 31);
234
+ }
235
+ getYearDays(year) {
236
+ return this.isLeapYear(year) ? 366 : 365;
237
+ }
238
+ getMonthLen(year, month) {
239
+ if (month === 2)
240
+ return this.isLeapYear(year) ? 29 : 28;
241
+ return m31.has(month) ? 31 : 30;
242
+ }
243
+ isLeapYear(year) {
244
+ if (year % 4 !== 0)
245
+ return false;
246
+ if (year % 100 !== 0)
247
+ return true;
248
+ return year % 400 === 0;
249
+ }
250
+ clone() {
251
+ return new LocalDate(this.year, this.month, this.day);
252
+ }
253
+ /**
254
+ * Converts LocalDate into instance of Date.
255
+ * Year, month and day will match.
256
+ * Hour, minute, second, ms will be 0.
257
+ * Timezone will match local timezone.
258
+ */
259
+ toDate() {
260
+ return new Date(this.year, this.month - 1, this.day);
261
+ }
262
+ toString() {
263
+ return [
264
+ String(this.year).padStart(4, '0'),
265
+ String(this.month).padStart(2, '0'),
266
+ String(this.day).padStart(2, '0'),
267
+ ].join('-');
268
+ }
269
+ toStringCompact() {
270
+ return [
271
+ String(this.year).padStart(4, '0'),
272
+ String(this.month).padStart(2, '0'),
273
+ String(this.day).padStart(2, '0'),
274
+ ].join('');
275
+ }
276
+ toJSON() {
277
+ return this.toString();
278
+ }
279
+ }
280
+ /**
281
+ * Shortcut wrapper around `LocalDate.parse` / `LocalDate.today`
282
+ */
283
+ export function localDate(d) {
284
+ return d ? LocalDate.of(d) : LocalDate.today();
285
+ }
@@ -0,0 +1,299 @@
1
+ import { _assert } from '../error/assert';
2
+ /* eslint-disable no-dupe-class-members */
3
+ // Design choices:
4
+ // No milliseconds
5
+ // No timezone support, ISO8601 is parsed as LocalDateTime, discarding Timezone information
6
+ // Formats as unix timestamp, ISO8601 or "pretty string"
7
+ // toString and .toJSON formats as unix timestamp
8
+ // No "unixMillis", just pure unixtimestamp
9
+ // .valueOf returns unix timestamp (no millis)
10
+ // Prevents dayjs(undefined) being dayjs.now()
11
+ // Validates on parse, throws if invalid. Doesn't allow invalid objects
12
+ /**
13
+ * @experimental
14
+ */
15
+ export class LocalTime {
16
+ constructor($date) {
17
+ this.$date = $date;
18
+ }
19
+ /**
20
+ * Parses input String into LocalDate.
21
+ * Input can already be a LocalDate - it is returned as-is in that case.
22
+ */
23
+ static of(d) {
24
+ if (d instanceof LocalTime)
25
+ return d;
26
+ if (d instanceof Date)
27
+ return new LocalTime(d);
28
+ if (typeof d === 'number') {
29
+ // unix timestamp
30
+ return new LocalTime(new Date(d * 1000));
31
+ }
32
+ const date = new Date(d);
33
+ // validation
34
+ if (isNaN(date.getDate())) {
35
+ throw new TypeError(`Cannot parse "${d}" into LocalTime`);
36
+ }
37
+ return new LocalTime(date);
38
+ }
39
+ static unix(ts) {
40
+ return new LocalTime(new Date(ts * 1000));
41
+ }
42
+ static now() {
43
+ return this.of(new Date());
44
+ }
45
+ static fromComponents(c) {
46
+ return new LocalTime(new Date(c.year, c.month - 1, c.day, c.hour, c.minute, c.second));
47
+ }
48
+ get(unit) {
49
+ if (unit === 'year') {
50
+ return this.$date.getFullYear();
51
+ }
52
+ if (unit === 'month') {
53
+ return this.$date.getMonth() + 1;
54
+ }
55
+ if (unit === 'day') {
56
+ return this.$date.getDate();
57
+ }
58
+ if (unit === 'hour') {
59
+ return this.$date.getHours();
60
+ }
61
+ if (unit === 'minute') {
62
+ return this.$date.getMinutes();
63
+ }
64
+ // second
65
+ return this.$date.getSeconds();
66
+ }
67
+ set(unit, v, mutate = false) {
68
+ const t = mutate ? this : this.clone();
69
+ if (unit === 'year') {
70
+ t.$date.setFullYear(v);
71
+ }
72
+ else if (unit === 'month') {
73
+ t.$date.setMonth(v - 1);
74
+ }
75
+ else if (unit === 'day') {
76
+ t.$date.setDate(v);
77
+ }
78
+ else if (unit === 'hour') {
79
+ t.$date.setHours(v);
80
+ }
81
+ else if (unit === 'minute') {
82
+ t.$date.setMinutes(v);
83
+ }
84
+ else if (unit === 'second') {
85
+ t.$date.setSeconds(v);
86
+ }
87
+ return t;
88
+ }
89
+ year(v) {
90
+ return v === undefined ? this.$date.getFullYear() : this.set('year', v);
91
+ }
92
+ month(v) {
93
+ return v === undefined ? this.$date.getMonth() + 1 : this.set('month', v);
94
+ }
95
+ date(v) {
96
+ return v === undefined ? this.$date.getDate() : this.set('day', v);
97
+ }
98
+ hour(v) {
99
+ return v === undefined ? this.$date.getHours() : this.set('hour', v);
100
+ }
101
+ minute(v) {
102
+ return v === undefined ? this.$date.getMinutes() : this.set('minute', v);
103
+ }
104
+ second(v) {
105
+ return v === undefined ? this.$date.getSeconds() : this.set('second', v);
106
+ }
107
+ setComponents(c, mutate = false) {
108
+ const d = mutate ? this.$date : new Date(this.$date);
109
+ if (c.year) {
110
+ d.setFullYear(c.year);
111
+ }
112
+ if (c.month) {
113
+ d.setMonth(c.month - 1);
114
+ }
115
+ if (c.day) {
116
+ d.setDate(c.day);
117
+ }
118
+ if (c.hour !== undefined) {
119
+ d.setHours(c.hour);
120
+ }
121
+ if (c.minute !== undefined) {
122
+ d.setMinutes(c.minute);
123
+ }
124
+ if (c.second !== undefined) {
125
+ d.setSeconds(c.second);
126
+ }
127
+ return mutate ? this : new LocalTime(d);
128
+ }
129
+ add(num, unit, mutate = false) {
130
+ return this.set(unit, this.get(unit) + num, mutate);
131
+ }
132
+ subtract(num, unit, mutate = false) {
133
+ return this.add(-num, unit, mutate);
134
+ }
135
+ absDiff(other, unit) {
136
+ return Math.abs(this.diff(other, unit));
137
+ }
138
+ diff(other, unit) {
139
+ const date2 = LocalTime.of(other).$date;
140
+ if (unit === 'year') {
141
+ return this.$date.getFullYear() - date2.getFullYear();
142
+ }
143
+ if (unit === 'month') {
144
+ return ((this.$date.getFullYear() - date2.getFullYear()) * 12 +
145
+ this.$date.getMonth() -
146
+ date2.getMonth());
147
+ }
148
+ const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000;
149
+ let r;
150
+ if (unit === 'day') {
151
+ r = secDiff / (24 * 60 * 60);
152
+ }
153
+ else if (unit === 'hour') {
154
+ r = secDiff / (60 * 60);
155
+ }
156
+ else if (unit === 'minute') {
157
+ r = secDiff / 60;
158
+ }
159
+ else {
160
+ // unit === 'second'
161
+ r = secDiff;
162
+ }
163
+ r = r < 0 ? -Math.floor(-r) : Math.floor(r);
164
+ if (Object.is(r, -0))
165
+ return 0;
166
+ return r;
167
+ }
168
+ startOf(unit, mutate = false) {
169
+ if (unit === 'second')
170
+ return this;
171
+ if (mutate) {
172
+ const d = this.$date;
173
+ d.setSeconds(0);
174
+ if (unit === 'minute')
175
+ return this;
176
+ d.setMinutes(0);
177
+ if (unit === 'hour')
178
+ return this;
179
+ d.setHours(0);
180
+ if (unit === 'day')
181
+ return this;
182
+ d.setDate(0);
183
+ if (unit === 'month')
184
+ return this;
185
+ d.setMonth(0);
186
+ return this;
187
+ }
188
+ const c = this.components();
189
+ c.second = 0;
190
+ if (unit === 'year') {
191
+ c.month = c.day = 1;
192
+ c.hour = c.minute = 0;
193
+ }
194
+ else if (unit === 'month') {
195
+ c.day = 1;
196
+ c.hour = c.minute = 0;
197
+ }
198
+ else if (unit === 'day') {
199
+ c.hour = c.minute = 0;
200
+ }
201
+ else if (unit === 'hour') {
202
+ c.minute = 0;
203
+ }
204
+ return LocalTime.fromComponents(c);
205
+ }
206
+ static sort(items, mutate = false, descending = false) {
207
+ const mod = descending ? -1 : 1;
208
+ return (mutate ? items : [...items]).sort((a, b) => {
209
+ const v1 = a.$date.valueOf();
210
+ const v2 = b.$date.valueOf();
211
+ if (v1 === v2)
212
+ return 0;
213
+ return (v1 < v2 ? -1 : 1) * mod;
214
+ });
215
+ }
216
+ static earliestOrUndefined(items) {
217
+ return items.length ? LocalTime.earliest(items) : undefined;
218
+ }
219
+ static earliest(items) {
220
+ _assert(items.length, 'LocalTime.earliest called on empty array');
221
+ return items.reduce((min, item) => (min.isSameOrBefore(item) ? min : item));
222
+ }
223
+ static latestOrUndefined(items) {
224
+ return items.length ? LocalTime.latest(items) : undefined;
225
+ }
226
+ static latest(items) {
227
+ _assert(items.length, 'LocalTime.latest called on empty array');
228
+ return items.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
229
+ }
230
+ isSame(d) {
231
+ return this.cmp(d) === 0;
232
+ }
233
+ isBefore(d) {
234
+ return this.cmp(d) === -1;
235
+ }
236
+ isSameOrBefore(d) {
237
+ return this.cmp(d) <= 0;
238
+ }
239
+ isAfter(d) {
240
+ return this.cmp(d) === 1;
241
+ }
242
+ isSameOrAfter(d) {
243
+ return this.cmp(d) >= 0;
244
+ }
245
+ /**
246
+ * Returns 1 if this > d
247
+ * returns 0 if they are equal
248
+ * returns -1 if this < d
249
+ */
250
+ cmp(d) {
251
+ const t1 = this.$date.valueOf();
252
+ const t2 = LocalTime.of(d).$date.valueOf();
253
+ if (t1 === t2)
254
+ return 0;
255
+ return t1 < t2 ? -1 : 1;
256
+ }
257
+ // todo: endOf
258
+ components() {
259
+ return {
260
+ year: this.$date.getFullYear(),
261
+ month: this.$date.getMonth() + 1,
262
+ day: this.$date.getDate(),
263
+ hour: this.$date.getHours(),
264
+ minute: this.$date.getMinutes(),
265
+ second: this.$date.getSeconds(),
266
+ };
267
+ }
268
+ getDate() {
269
+ return this.$date;
270
+ }
271
+ clone() {
272
+ return new LocalTime(new Date(this.$date));
273
+ }
274
+ unix() {
275
+ return Math.floor(this.$date.valueOf() / 1000);
276
+ }
277
+ valueOf() {
278
+ return Math.floor(this.$date.valueOf() / 1000);
279
+ }
280
+ toISO8601() {
281
+ return this.$date.toISOString().slice(0, 19);
282
+ }
283
+ toPretty() {
284
+ return this.$date.toISOString().slice(0, 19).split('T').join(' ');
285
+ }
286
+ toString() {
287
+ return String(this.unix());
288
+ }
289
+ toJSON() {
290
+ return this.unix();
291
+ }
292
+ }
293
+ /**
294
+ * Shortcut wrapper around `LocalDate.parse` / `LocalDate.today`
295
+ */
296
+ export function localTime(d) {
297
+ return d ? LocalTime.of(d) : LocalTime.now();
298
+ }
299
+ // todo: range
package/dist-esm/index.js CHANGED
@@ -57,4 +57,6 @@ import { PQueue } from './promise/pQueue';
57
57
  export * from './seq/seq';
58
58
  export * from './math/stack.util';
59
59
  export * from './string/leven';
60
+ export * from './datetime/localDate';
61
+ export * from './datetime/localTime';
60
62
  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, };
@@ -138,15 +138,15 @@ is.array = (value, assertion) => {
138
138
  }
139
139
  return value.every(assertion);
140
140
  };
141
- is.buffer = (value) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = value) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.isBuffer) === null || _c === void 0 ? void 0 : _c.call(_b, value)) !== null && _d !== void 0 ? _d : false; };
141
+ is.buffer = (value) => { var _a, _b, _c; return (_c = (_b = (_a = value === null || value === void 0 ? void 0 : value.constructor) === null || _a === void 0 ? void 0 : _a.isBuffer) === null || _b === void 0 ? void 0 : _b.call(_a, value)) !== null && _c !== void 0 ? _c : false; };
142
142
  is.nullOrUndefined = (value) => is.null_(value) || is.undefined(value);
143
143
  is.object = (value) => !is.null_(value) && (typeof value === 'object' || is.function_(value));
144
- is.iterable = (value) => { var _a; return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.iterator]); };
145
- is.asyncIterable = (value) => { var _a; return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.asyncIterator]); };
144
+ is.iterable = (value) => is.function_(value === null || value === void 0 ? void 0 : value[Symbol.iterator]);
145
+ is.asyncIterable = (value) => is.function_(value === null || value === void 0 ? void 0 : value[Symbol.asyncIterator]);
146
146
  is.generator = (value) => is.iterable(value) && is.function_(value.next) && is.function_(value.throw);
147
147
  is.asyncGenerator = (value) => is.asyncIterable(value) && is.function_(value.next) && is.function_(value.throw);
148
148
  is.nativePromise = (value) => isObjectOfType('Promise')(value);
149
- const hasPromiseAPI = (value) => { var _a, _b; return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a.then) && is.function_((_b = value) === null || _b === void 0 ? void 0 : _b.catch); };
149
+ const hasPromiseAPI = (value) => is.function_(value === null || value === void 0 ? void 0 : value.then) && is.function_(value === null || value === void 0 ? void 0 : value.catch);
150
150
  is.promise = (value) => is.nativePromise(value) || hasPromiseAPI(value);
151
151
  is.generatorFunction = isObjectOfType('GeneratorFunction');
152
152
  is.asyncGeneratorFunction = (value) => getObjectType(value) === 'AsyncGeneratorFunction';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.88.0",
3
+ "version": "14.89.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -14,6 +14,7 @@
14
14
  "@naturalcycles/bench-lib": "^1.5.0",
15
15
  "@naturalcycles/dev-lib": "^12.0.0",
16
16
  "@naturalcycles/nodejs-lib": "^12.33.4",
17
+ "@naturalcycles/time-lib": "^3.5.1",
17
18
  "@types/node": "^17.0.4",
18
19
  "jest": "^27.0.1",
19
20
  "patch-package": "^6.2.1",
@@ -0,0 +1,73 @@
1
+ import { LocalDateUnit, LocalDate, LocalDateConfig } from '../datetime/localDate'
2
+
3
+ export class LazyLocalDate {
4
+ constructor(private str: string) {}
5
+
6
+ private ld?: LocalDate
7
+
8
+ eq(d: LocalDateConfig): boolean {
9
+ if (typeof d === 'string') return d === this.str
10
+ this.ld ||= LocalDate.of(this.str)
11
+ return this.ld.isSame(d)
12
+ }
13
+
14
+ lt(d: LocalDateConfig): boolean {
15
+ return this.cmp(d) === -1
16
+ }
17
+
18
+ lte(d: LocalDateConfig): boolean {
19
+ return this.cmp(d) <= 0
20
+ }
21
+
22
+ gt(d: LocalDateConfig): boolean {
23
+ return this.cmp(d) === 1
24
+ }
25
+
26
+ gte(d: LocalDateConfig): boolean {
27
+ return this.cmp(d) >= 0
28
+ }
29
+
30
+ cmp(d: LocalDateConfig): -1 | 0 | 1 {
31
+ if (typeof d === 'string') {
32
+ return this.str < d ? -1 : this.str > d ? 1 : 0
33
+ }
34
+
35
+ this.ld ||= LocalDate.of(this.str)
36
+ return this.ld.cmp(d)
37
+ }
38
+
39
+ absDiff(d: LocalDateConfig, unit: LocalDateUnit): number {
40
+ return Math.abs(this.diff(d, unit))
41
+ }
42
+
43
+ diff(d: LocalDateConfig, unit: LocalDateUnit): number {
44
+ this.ld ||= LocalDate.of(this.str)
45
+ return this.ld.diff(d, unit)
46
+ }
47
+
48
+ add(num: number, unit: LocalDateUnit): LocalDate {
49
+ this.ld ||= LocalDate.of(this.str)
50
+ return this.ld.add(num, unit)
51
+ }
52
+
53
+ subtract(num: number, unit: LocalDateUnit): LocalDate {
54
+ return this.add(-num, unit)
55
+ }
56
+
57
+ clone(): LazyLocalDate {
58
+ return new LazyLocalDate(this.str)
59
+ }
60
+
61
+ toDate(): Date {
62
+ this.ld ||= LocalDate.of(this.str)
63
+ return this.ld.toDate()
64
+ }
65
+
66
+ toString(): string {
67
+ return this.str
68
+ }
69
+
70
+ toJSON(): string {
71
+ return this.str
72
+ }
73
+ }