@thisisagile/easy 18.11.0 → 18.11.1
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/README.md +1 -1
- package/dist/{chunk-TMVZSMUA.mjs → chunk-5VP4WNID.mjs} +2 -2
- package/dist/chunk-GRDUTNMZ.mjs +272 -0
- package/dist/chunk-GRDUTNMZ.mjs.map +1 -0
- package/dist/domain/Audit.mjs +2 -2
- package/dist/domain/DateTime.d.ts +7 -5
- package/dist/domain/DateTime.mjs +1 -1
- package/dist/domain/Entity.mjs +2 -2
- package/dist/index.js +165 -33
- package/dist/index.js.map +1 -1
- package/dist/utils/Period.mjs +1 -1
- package/package.json +9 -4
- package/src/domain/DateTime.ts +206 -40
- package/dist/chunk-EOHHPAAY.mjs +0 -140
- package/dist/chunk-EOHHPAAY.mjs.map +0 -1
- /package/dist/{chunk-TMVZSMUA.mjs.map → chunk-5VP4WNID.mjs.map} +0 -0
package/dist/utils/Period.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thisisagile/easy",
|
|
3
|
-
"version": "18.11.
|
|
3
|
+
"version": "18.11.1",
|
|
4
4
|
"description": "Straightforward library for building domain-driven microservice architectures",
|
|
5
5
|
"author": "Sander Hoogendoorn",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,7 +25,13 @@
|
|
|
25
25
|
"test": "yarn g:jest --coverage",
|
|
26
26
|
"prepack": "yarn g:copy-readme"
|
|
27
27
|
},
|
|
28
|
-
"sideEffects":
|
|
28
|
+
"sideEffects": [
|
|
29
|
+
"./src/domain/DateTime.ts",
|
|
30
|
+
"./src/types/Meta.ts",
|
|
31
|
+
"./dist/domain/DateTime.*",
|
|
32
|
+
"./dist/types/Meta.*",
|
|
33
|
+
"./dist/index.js"
|
|
34
|
+
],
|
|
29
35
|
"files": [
|
|
30
36
|
"dist",
|
|
31
37
|
"src"
|
|
@@ -36,15 +42,14 @@
|
|
|
36
42
|
"devDependencies": {
|
|
37
43
|
"@thisisagile/easy-test": "*",
|
|
38
44
|
"@types/form-urlencoded": "^4.4.2",
|
|
39
|
-
"@types/luxon": "3.4.2",
|
|
40
45
|
"@types/validator": "^13.12.2"
|
|
41
46
|
},
|
|
42
47
|
"dependencies": {
|
|
43
48
|
"@types/uuid": "^9.0.8",
|
|
44
49
|
"axios": "^1.7.9",
|
|
50
|
+
"dayjs": "^1.11.21",
|
|
45
51
|
"form-urlencoded": "^6.1.5",
|
|
46
52
|
"jwt-decode": "^4.0.0",
|
|
47
|
-
"luxon": "^3.5.0",
|
|
48
53
|
"reflect-metadata": "^0.2.2",
|
|
49
54
|
"uuid": "^9.0.1",
|
|
50
55
|
"validator": "^13.12.0"
|
package/src/domain/DateTime.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import dayjs, { Dayjs, ManipulateType, OpUnitType, QUnitType } from 'dayjs';
|
|
2
|
+
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
|
3
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
4
|
+
import isoWeek from 'dayjs/plugin/isoWeek';
|
|
5
|
+
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
|
6
|
+
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
|
|
7
|
+
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
8
|
+
import timezone from 'dayjs/plugin/timezone';
|
|
9
|
+
import utc from 'dayjs/plugin/utc';
|
|
10
|
+
import 'dayjs/locale/de';
|
|
11
|
+
import 'dayjs/locale/nl';
|
|
2
12
|
import { Value } from '../types/Value';
|
|
3
13
|
import { Optional } from '../types/Types';
|
|
4
|
-
import { choose } from '../types/Case';
|
|
5
14
|
import { isDefined, isNumber, isString } from '../types/Is';
|
|
6
15
|
import { isDate } from '../types/IsDate';
|
|
7
16
|
import { isA } from '../types/IsA';
|
|
@@ -10,11 +19,30 @@ import { JsonValue } from '../types/Json';
|
|
|
10
19
|
import { seconds } from '../utils/Seconds';
|
|
11
20
|
import { tryTo } from '../types/Try';
|
|
12
21
|
import { use } from '../types/Constructor';
|
|
22
|
+
import { choose } from '../types/Case';
|
|
13
23
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
dayjs.extend(utc);
|
|
25
|
+
dayjs.extend(timezone);
|
|
26
|
+
dayjs.extend(customParseFormat);
|
|
27
|
+
dayjs.extend(localizedFormat);
|
|
28
|
+
dayjs.extend(relativeTime);
|
|
29
|
+
dayjs.extend(isoWeek);
|
|
30
|
+
dayjs.extend(advancedFormat);
|
|
31
|
+
dayjs.extend(quarterOfYear);
|
|
32
|
+
dayjs.tz.setDefault('UTC');
|
|
33
|
+
|
|
34
|
+
export type DateTimeUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond';
|
|
35
|
+
export type DurationUnit =
|
|
36
|
+
| DateTimeUnit
|
|
37
|
+
| 'years'
|
|
38
|
+
| 'quarters'
|
|
39
|
+
| 'months'
|
|
40
|
+
| 'weeks'
|
|
41
|
+
| 'days'
|
|
42
|
+
| 'hours'
|
|
43
|
+
| 'minutes'
|
|
44
|
+
| 'seconds'
|
|
45
|
+
| 'milliseconds';
|
|
18
46
|
export type Duration = Partial<Record<DurationUnit, number>>;
|
|
19
47
|
|
|
20
48
|
export type DiffOptions = {
|
|
@@ -23,30 +51,65 @@ export type DiffOptions = {
|
|
|
23
51
|
|
|
24
52
|
export type DatetimeInput = string | number | Date | DateTime | null;
|
|
25
53
|
|
|
54
|
+
type DateTimeConstructorInput = DatetimeInput | Dayjs;
|
|
55
|
+
type ZonedDayjs = Dayjs & { $x?: { $timezone?: string } };
|
|
56
|
+
|
|
57
|
+
const invalidDate = dayjs.utc(Number.NaN);
|
|
58
|
+
const isDayjs = (value: unknown): value is Dayjs => dayjs.isDayjs(value);
|
|
59
|
+
const isoFormats = [
|
|
60
|
+
'YYYY-MM-DD',
|
|
61
|
+
'YYYY-MM-DDTHH:mm',
|
|
62
|
+
'YYYY-MM-DDTHH:mm:ss',
|
|
63
|
+
'YYYY-MM-DDTHH:mm:ss.SSS',
|
|
64
|
+
'YYYY-MM-DDTHH:mm[Z]',
|
|
65
|
+
'YYYY-MM-DDTHH:mm:ss[Z]',
|
|
66
|
+
'YYYY-MM-DDTHH:mm:ss.SSS[Z]',
|
|
67
|
+
'YYYY-MM-DDTHH:mmZ',
|
|
68
|
+
'YYYY-MM-DDTHH:mmZZ',
|
|
69
|
+
'YYYY-MM-DDTHH:mm:ssZ',
|
|
70
|
+
'YYYY-MM-DDTHH:mm:ssZZ',
|
|
71
|
+
'YYYY-MM-DDTHH:mm:ss.SSSZ',
|
|
72
|
+
'YYYY-MM-DDTHH:mm:ss.SSSZZ',
|
|
73
|
+
];
|
|
74
|
+
const fixedUnitMilliseconds: Partial<Record<DurationUnit, number>> = {
|
|
75
|
+
day: 86400000,
|
|
76
|
+
days: 86400000,
|
|
77
|
+
week: 604800000,
|
|
78
|
+
weeks: 604800000,
|
|
79
|
+
};
|
|
80
|
+
const calendarUnitMonths: Partial<Record<DurationUnit, number>> = {
|
|
81
|
+
month: 1,
|
|
82
|
+
months: 1,
|
|
83
|
+
quarter: 3,
|
|
84
|
+
quarters: 3,
|
|
85
|
+
year: 12,
|
|
86
|
+
years: 12,
|
|
87
|
+
};
|
|
88
|
+
|
|
26
89
|
export class DateTime extends Value<Optional<string>> {
|
|
27
|
-
protected readonly
|
|
90
|
+
protected readonly date: Dayjs;
|
|
28
91
|
|
|
29
92
|
constructor(value?: DatetimeInput);
|
|
30
93
|
constructor(value?: string, format?: string);
|
|
31
|
-
constructor(value?:
|
|
32
|
-
const
|
|
33
|
-
.type(
|
|
34
|
-
.type(
|
|
35
|
-
.type(
|
|
36
|
-
.type(
|
|
37
|
-
|
|
38
|
-
.else(
|
|
39
|
-
|
|
40
|
-
super(
|
|
41
|
-
this.
|
|
94
|
+
constructor(value?: DateTimeConstructorInput, format?: string) {
|
|
95
|
+
const date = choose<DateTimeConstructorInput | undefined>(value)
|
|
96
|
+
.type(isDayjs, date => date)
|
|
97
|
+
.type(isDateTime, dateTime => dateTime.date)
|
|
98
|
+
.type(isNumber, timestamp => dayjs.utc(timestamp))
|
|
99
|
+
.type(isDate, date => dayjs.utc(date))
|
|
100
|
+
.type(isString, string => (string === '' ? invalidDate : format ? parseFormatted(string, format) : parseIso(string)))
|
|
101
|
+
.else(invalidDate);
|
|
102
|
+
|
|
103
|
+
super(date.isValid() ? formatDateTime(date) : undefined);
|
|
104
|
+
this.date = date;
|
|
42
105
|
}
|
|
43
106
|
|
|
44
107
|
static get now(): DateTime {
|
|
45
|
-
return
|
|
108
|
+
return fromDayjs(dayjs.utc(Date.now()));
|
|
46
109
|
}
|
|
47
110
|
|
|
48
111
|
get isValid(): boolean {
|
|
49
|
-
return isDefined(this.value) && this.
|
|
112
|
+
return isDefined(this.value) && this.date.isValid();
|
|
50
113
|
}
|
|
51
114
|
|
|
52
115
|
/**
|
|
@@ -72,8 +135,8 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
72
135
|
return this.withZone('Europe/Warsaw');
|
|
73
136
|
}
|
|
74
137
|
|
|
75
|
-
protected get utc():
|
|
76
|
-
return this.
|
|
138
|
+
protected get utc(): Dayjs {
|
|
139
|
+
return this.date.utc();
|
|
77
140
|
}
|
|
78
141
|
|
|
79
142
|
from(locale?: string): string;
|
|
@@ -85,23 +148,23 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
85
148
|
use((isString(dateOrLocale) ? dateOrLocale : maybeLocale) ?? 'en', locale =>
|
|
86
149
|
ifDefined(
|
|
87
150
|
isA<DateTime>(dateOrLocale) ? dateOrLocale : undefined,
|
|
88
|
-
d => this.utc.
|
|
89
|
-
() => this.utc.
|
|
151
|
+
d => this.utc.locale(toDayjsLocale(locale)).from(d.utc),
|
|
152
|
+
() => this.utc.locale(toDayjsLocale(locale)).from(dayjs.utc(Date.now()))
|
|
90
153
|
)
|
|
91
154
|
) ?? ''
|
|
92
155
|
);
|
|
93
156
|
}
|
|
94
157
|
|
|
95
158
|
isAfter(dt: DateTime): boolean {
|
|
96
|
-
return this.utc > dt.utc;
|
|
159
|
+
return this.utc.valueOf() > dt.utc.valueOf();
|
|
97
160
|
}
|
|
98
161
|
|
|
99
162
|
isBefore(dt: DateTime): boolean {
|
|
100
|
-
return this.utc < dt.utc;
|
|
163
|
+
return this.utc.valueOf() < dt.utc.valueOf();
|
|
101
164
|
}
|
|
102
165
|
|
|
103
166
|
equals(dt: DateTime): boolean {
|
|
104
|
-
return this.utc.
|
|
167
|
+
return this.utc.valueOf() === dt.utc.valueOf();
|
|
105
168
|
}
|
|
106
169
|
|
|
107
170
|
add(n: number, unit?: DurationUnit): DateTime;
|
|
@@ -109,7 +172,7 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
109
172
|
add(duration: Duration): DateTime;
|
|
110
173
|
|
|
111
174
|
add(n: number | Duration, unit: DurationUnit = 'day'): DateTime {
|
|
112
|
-
return
|
|
175
|
+
return fromDayjs(change(this.date, n, unit, 'add'));
|
|
113
176
|
}
|
|
114
177
|
|
|
115
178
|
subtract(n: number, unit?: DurationUnit): DateTime;
|
|
@@ -117,27 +180,28 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
117
180
|
subtract(duration: Duration): DateTime;
|
|
118
181
|
|
|
119
182
|
subtract(n: number | Duration, unit: DurationUnit = 'day'): DateTime {
|
|
120
|
-
return
|
|
183
|
+
return fromDayjs(change(this.date, n, unit, 'subtract'));
|
|
121
184
|
}
|
|
122
185
|
|
|
123
186
|
diff(other: DateTime, unit: DateTimeUnit = 'day', opts?: DiffOptions): number {
|
|
124
|
-
return Math[opts?.rounding ?? 'floor'](this.utc.diff(other.utc
|
|
187
|
+
return Math[opts?.rounding ?? 'floor'](this.utc.diff(other.utc, toDayjsUnit(unit) as QUnitType | OpUnitType, true));
|
|
125
188
|
}
|
|
126
189
|
|
|
127
190
|
startOf(unit: DateTimeUnit = 'day'): DateTime {
|
|
128
|
-
return
|
|
191
|
+
return fromDayjs(this.date.startOf(toDayjsBoundaryUnit(unit)));
|
|
129
192
|
}
|
|
130
193
|
|
|
131
194
|
endOf(unit: DateTimeUnit = 'day'): DateTime {
|
|
132
|
-
return
|
|
195
|
+
return fromDayjs(this.date.endOf(toDayjsBoundaryUnit(unit)));
|
|
133
196
|
}
|
|
134
197
|
|
|
135
198
|
isWeekend(): boolean {
|
|
136
|
-
|
|
199
|
+
const day = this.date.day();
|
|
200
|
+
return day === 0 || day === 6;
|
|
137
201
|
}
|
|
138
202
|
|
|
139
203
|
withZone(zone: string): DateTime {
|
|
140
|
-
return
|
|
204
|
+
return fromDayjs(this.date.tz(zone));
|
|
141
205
|
}
|
|
142
206
|
|
|
143
207
|
toString(): string {
|
|
@@ -145,15 +209,30 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
145
209
|
}
|
|
146
210
|
|
|
147
211
|
toJSON(): JsonValue {
|
|
148
|
-
return this.utc.
|
|
212
|
+
return this.isValid ? this.utc.format('YYYY-MM-DDTHH:mm:ss.SSS[Z]') : null;
|
|
149
213
|
}
|
|
150
214
|
|
|
151
215
|
toFormat(format: string): string {
|
|
152
|
-
return this.
|
|
216
|
+
return this.isValid ? this.date.format(toDayjsFormat(format)) : '';
|
|
153
217
|
}
|
|
154
218
|
|
|
155
219
|
toLocale(locale = 'nl-NL', format = 'D'): string {
|
|
156
|
-
|
|
220
|
+
if (!this.isValid) return '';
|
|
221
|
+
|
|
222
|
+
if (format === 'D') return formatWithIntl(this.date, locale, { year: 'numeric', month: 'numeric', day: 'numeric' });
|
|
223
|
+
if (format === 'DDD') return formatWithIntl(this.date, locale, { dateStyle: 'long' });
|
|
224
|
+
if (format === 'ffff') {
|
|
225
|
+
return formatWithIntl(this.date, locale, {
|
|
226
|
+
weekday: 'long',
|
|
227
|
+
year: 'numeric',
|
|
228
|
+
month: 'long',
|
|
229
|
+
day: 'numeric',
|
|
230
|
+
hour: 'numeric',
|
|
231
|
+
minute: '2-digit',
|
|
232
|
+
timeZoneName: timezoneOf(this.date) ? 'long' : 'short',
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return this.date.locale(toDayjsLocale(locale)).format(toDayjsFormat(format));
|
|
157
236
|
}
|
|
158
237
|
|
|
159
238
|
toFull(locale?: string): string {
|
|
@@ -161,11 +240,11 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
161
240
|
}
|
|
162
241
|
|
|
163
242
|
toDate(): Optional<Date> {
|
|
164
|
-
return this.isValid ? this.utc.
|
|
243
|
+
return this.isValid ? this.utc.toDate() : undefined;
|
|
165
244
|
}
|
|
166
245
|
|
|
167
246
|
toEpoch(): number {
|
|
168
|
-
return this.
|
|
247
|
+
return this.date.valueOf();
|
|
169
248
|
}
|
|
170
249
|
|
|
171
250
|
ago(end: DateTime = DateTime.now): string {
|
|
@@ -174,7 +253,7 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
174
253
|
|
|
175
254
|
withClock(clock: DateTime): DateTime {
|
|
176
255
|
return tryTo(() => [this.toDate() as Date, clock.toDate() as Date])
|
|
177
|
-
.map(([td, cd]) => new Date(td.
|
|
256
|
+
.map(([td, cd]) => new Date(Date.UTC(td.getUTCFullYear(), td.getUTCMonth(), td.getUTCDate(), cd.getUTCHours(), cd.getUTCMinutes(), cd.getUTCSeconds())))
|
|
178
257
|
.map(d => new DateTime(d)).value;
|
|
179
258
|
}
|
|
180
259
|
}
|
|
@@ -182,3 +261,90 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
182
261
|
export const isDateTime = (dt?: unknown): dt is DateTime => isDefined(dt) && dt instanceof DateTime;
|
|
183
262
|
|
|
184
263
|
export const dt = (dt?: DatetimeInput): DateTime => new DateTime(dt);
|
|
264
|
+
|
|
265
|
+
const parseIso = (value: string): Dayjs => {
|
|
266
|
+
const offset = offsetOf(value);
|
|
267
|
+
if (offset) {
|
|
268
|
+
const date = dayjs.utc(value);
|
|
269
|
+
return date.isValid() ? inOffsetZone(date, offset) : invalidDate;
|
|
270
|
+
}
|
|
271
|
+
return dayjs(value, isoFormats, true).isValid() ? dayjs.utc(value) : invalidDate;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const parseFormatted = (value: string, format: string): Dayjs => {
|
|
275
|
+
const dayjsFormat = toDayjsFormat(format);
|
|
276
|
+
const offset = offsetOf(value);
|
|
277
|
+
if (format.includes('ZZZ') && offset) {
|
|
278
|
+
const iso = dayjs.utc(value);
|
|
279
|
+
return iso.isValid() ? inOffsetZone(iso, offset) : invalidDate;
|
|
280
|
+
}
|
|
281
|
+
return dayjs.utc(value, dayjsFormat, true);
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const offsetOf = (value: string): string | undefined => value.match(/([+-]\d{2}:?\d{2})$/)?.[1];
|
|
285
|
+
|
|
286
|
+
const fromDayjs = (date: Dayjs): DateTime => new DateTime(date as unknown as DatetimeInput);
|
|
287
|
+
|
|
288
|
+
const formatDateTime = (date: Dayjs): string => {
|
|
289
|
+
const formatted = date.format('YYYY-MM-DDTHH:mm:ss.SSSZ');
|
|
290
|
+
return timezoneOf(date) ? formatted : formatted.replace('+00:00', 'Z');
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const change = (date: Dayjs, value: number | Duration, unit: DurationUnit, direction: 'add' | 'subtract'): Dayjs => {
|
|
294
|
+
if (isNumber(value)) return changeUnit(date, value, unit, direction);
|
|
295
|
+
return Object.entries(value).reduce((result, [durationUnit, durationValue]) => changeUnit(result, durationValue ?? 0, durationUnit as DurationUnit, direction), date);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const changeUnit = (date: Dayjs, value: number, unit: DurationUnit, direction: 'add' | 'subtract'): Dayjs => {
|
|
299
|
+
const amount = direction === 'add' ? value : -value;
|
|
300
|
+
const milliseconds = fixedUnitMilliseconds[unit];
|
|
301
|
+
const months = calendarUnitMonths[unit];
|
|
302
|
+
|
|
303
|
+
if (months && !Number.isInteger(value)) return addMonths(date, amount * months);
|
|
304
|
+
if (milliseconds && !Number.isInteger(value)) return date.add(amount * milliseconds, 'millisecond');
|
|
305
|
+
return date.add(amount, toDayjsUnit(unit));
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const addMonths = (date: Dayjs, months: number): Dayjs => {
|
|
309
|
+
const wholeMonths = Math.trunc(months);
|
|
310
|
+
const fraction = months - wholeMonths;
|
|
311
|
+
const shifted = date.add(wholeMonths, 'month');
|
|
312
|
+
if (fraction === 0) return shifted;
|
|
313
|
+
|
|
314
|
+
const next = shifted.add(months > 0 ? 1 : -1, 'month');
|
|
315
|
+
return shifted.add((next.valueOf() - shifted.valueOf()) * Math.abs(fraction), 'millisecond');
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const inOffsetZone = (date: Dayjs, offset: string): Dayjs => offsetToTimeZone(offset).map(zone => date.tz(zone)).or(date.utcOffset(offset));
|
|
319
|
+
|
|
320
|
+
const offsetToTimeZone = (offset: string) =>
|
|
321
|
+
tryTo(() => {
|
|
322
|
+
const [, sign, hours, minutes] = offset.match(/^([+-])(\d{2}):?(\d{2})$/) ?? [];
|
|
323
|
+
if (minutes !== '00') throw new Error();
|
|
324
|
+
if (hours === '00') return 'UTC';
|
|
325
|
+
return `Etc/GMT${sign === '+' ? '-' : '+'}${Number(hours)}`;
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const toDayjsUnit = (unit: DurationUnit): ManipulateType => unit.replace(/s$/, '') as ManipulateType;
|
|
329
|
+
|
|
330
|
+
const toDayjsBoundaryUnit = (unit: DateTimeUnit): OpUnitType => {
|
|
331
|
+
const dayjsUnit = toDayjsUnit(unit);
|
|
332
|
+
return (dayjsUnit === 'week' ? 'isoWeek' : dayjsUnit) as OpUnitType;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const toDayjsFormat = (format: string): string =>
|
|
336
|
+
format
|
|
337
|
+
.replace(/'([^']+)'/g, '[$1]')
|
|
338
|
+
.replace(/EEE/g, 'ddd')
|
|
339
|
+
.replace(/yyyy/g, 'YYYY')
|
|
340
|
+
.replace(/dd/g, 'DD')
|
|
341
|
+
.replace(/LLL/g, 'MMM')
|
|
342
|
+
.replace(/ZZZ/g, 'ZZ')
|
|
343
|
+
.replace(/hh/g, 'HH');
|
|
344
|
+
|
|
345
|
+
const toDayjsLocale = (locale: string): string => locale.toLowerCase().split('-')[0];
|
|
346
|
+
|
|
347
|
+
const formatWithIntl = (date: Dayjs, locale: string, options: Intl.DateTimeFormatOptions): string =>
|
|
348
|
+
new Intl.DateTimeFormat(locale, { ...options, timeZone: timezoneOf(date) ?? 'UTC' }).format(date.toDate());
|
|
349
|
+
|
|
350
|
+
const timezoneOf = (date: Dayjs): string | undefined => (date as ZonedDayjs).$x?.$timezone;
|
package/dist/chunk-EOHHPAAY.mjs
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
seconds
|
|
3
|
-
} from "./chunk-RF23BV6J.mjs";
|
|
4
|
-
import {
|
|
5
|
-
isDate
|
|
6
|
-
} from "./chunk-ADJAEGCT.mjs";
|
|
7
|
-
import {
|
|
8
|
-
choose,
|
|
9
|
-
ifDefined,
|
|
10
|
-
tryTo
|
|
11
|
-
} from "./chunk-I2VWZJ2K.mjs";
|
|
12
|
-
import {
|
|
13
|
-
Value
|
|
14
|
-
} from "./chunk-S3NSPQ7M.mjs";
|
|
15
|
-
import {
|
|
16
|
-
isA
|
|
17
|
-
} from "./chunk-D5IYAIMK.mjs";
|
|
18
|
-
import {
|
|
19
|
-
use
|
|
20
|
-
} from "./chunk-PF7HDF6B.mjs";
|
|
21
|
-
import {
|
|
22
|
-
isDefined,
|
|
23
|
-
isNumber,
|
|
24
|
-
isString
|
|
25
|
-
} from "./chunk-AAND4MKF.mjs";
|
|
26
|
-
|
|
27
|
-
// src/domain/DateTime.ts
|
|
28
|
-
import { DateTime as LuxonDateTime, Settings } from "luxon";
|
|
29
|
-
Settings.defaultZone = "utc";
|
|
30
|
-
var DateTime = class _DateTime extends Value {
|
|
31
|
-
luxon;
|
|
32
|
-
constructor(value, format) {
|
|
33
|
-
const luxon = choose(value).type(isString, (v) => format ? LuxonDateTime.fromFormat(v, format, { setZone: true }) : LuxonDateTime.fromISO(v, { setZone: true })).type(isNumber, (v) => LuxonDateTime.fromMillis(v)).type(isDate, (v) => LuxonDateTime.fromJSDate(v)).type(isDateTime, (v) => v.luxon).else(value instanceof LuxonDateTime ? value : LuxonDateTime.fromISO(void 0));
|
|
34
|
-
super(luxon.toISO() ?? void 0);
|
|
35
|
-
this.luxon = luxon;
|
|
36
|
-
}
|
|
37
|
-
static get now() {
|
|
38
|
-
return new _DateTime(LuxonDateTime.utc());
|
|
39
|
-
}
|
|
40
|
-
get isValid() {
|
|
41
|
-
return isDefined(this.value) && this.utc.isValid;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* @deprecated Deprecated in favor for DateTime.from as that also accepts locales and another DateTime
|
|
45
|
-
*/
|
|
46
|
-
get fromNow() {
|
|
47
|
-
return this.from();
|
|
48
|
-
}
|
|
49
|
-
get inAmsterdam() {
|
|
50
|
-
return this.withZone("Europe/Amsterdam");
|
|
51
|
-
}
|
|
52
|
-
get inNewYork() {
|
|
53
|
-
return this.withZone("America/New_York");
|
|
54
|
-
}
|
|
55
|
-
get inLondon() {
|
|
56
|
-
return this.withZone("Europe/London");
|
|
57
|
-
}
|
|
58
|
-
get inWarsaw() {
|
|
59
|
-
return this.withZone("Europe/Warsaw");
|
|
60
|
-
}
|
|
61
|
-
get utc() {
|
|
62
|
-
return this.luxon.setZone("utc");
|
|
63
|
-
}
|
|
64
|
-
from(dateOrLocale, maybeLocale) {
|
|
65
|
-
return use(
|
|
66
|
-
(isString(dateOrLocale) ? dateOrLocale : maybeLocale) ?? "en",
|
|
67
|
-
(locale) => ifDefined(
|
|
68
|
-
isA(dateOrLocale) ? dateOrLocale : void 0,
|
|
69
|
-
(d) => this.utc.setLocale(locale).toRelative({ base: d.utc }),
|
|
70
|
-
() => this.utc.setLocale(locale).toRelative()
|
|
71
|
-
)
|
|
72
|
-
) ?? "";
|
|
73
|
-
}
|
|
74
|
-
isAfter(dt2) {
|
|
75
|
-
return this.utc > dt2.utc;
|
|
76
|
-
}
|
|
77
|
-
isBefore(dt2) {
|
|
78
|
-
return this.utc < dt2.utc;
|
|
79
|
-
}
|
|
80
|
-
equals(dt2) {
|
|
81
|
-
return this.utc.hasSame(dt2.utc, "millisecond");
|
|
82
|
-
}
|
|
83
|
-
add(n, unit = "day") {
|
|
84
|
-
return new _DateTime(this.luxon.plus(isNumber(n) ? { [unit]: n } : n));
|
|
85
|
-
}
|
|
86
|
-
subtract(n, unit = "day") {
|
|
87
|
-
return new _DateTime(this.luxon.minus(isNumber(n) ? { [unit]: n } : n));
|
|
88
|
-
}
|
|
89
|
-
diff(other, unit = "day", opts) {
|
|
90
|
-
return Math[opts?.rounding ?? "floor"](this.utc.diff(other.utc).as(unit));
|
|
91
|
-
}
|
|
92
|
-
startOf(unit = "day") {
|
|
93
|
-
return new _DateTime(this.luxon.startOf(unit));
|
|
94
|
-
}
|
|
95
|
-
endOf(unit = "day") {
|
|
96
|
-
return new _DateTime(this.luxon.endOf(unit));
|
|
97
|
-
}
|
|
98
|
-
isWeekend() {
|
|
99
|
-
return this.luxon.isWeekend;
|
|
100
|
-
}
|
|
101
|
-
withZone(zone) {
|
|
102
|
-
return new _DateTime(this.luxon.setZone(zone));
|
|
103
|
-
}
|
|
104
|
-
toString() {
|
|
105
|
-
return this.value ?? "";
|
|
106
|
-
}
|
|
107
|
-
toJSON() {
|
|
108
|
-
return this.utc.toISO();
|
|
109
|
-
}
|
|
110
|
-
toFormat(format) {
|
|
111
|
-
return this.luxon.toFormat(format);
|
|
112
|
-
}
|
|
113
|
-
toLocale(locale = "nl-NL", format = "D") {
|
|
114
|
-
return this.luxon.setLocale(locale).toFormat(format);
|
|
115
|
-
}
|
|
116
|
-
toFull(locale) {
|
|
117
|
-
return this.toLocale(locale, "DDD");
|
|
118
|
-
}
|
|
119
|
-
toDate() {
|
|
120
|
-
return this.isValid ? this.utc.toJSDate() : void 0;
|
|
121
|
-
}
|
|
122
|
-
toEpoch() {
|
|
123
|
-
return this.luxon.toMillis();
|
|
124
|
-
}
|
|
125
|
-
ago(end = _DateTime.now) {
|
|
126
|
-
return seconds.toText(end.diff(this, "second"));
|
|
127
|
-
}
|
|
128
|
-
withClock(clock) {
|
|
129
|
-
return tryTo(() => [this.toDate(), clock.toDate()]).map(([td, cd]) => new Date(td.getFullYear(), td.getMonth(), td.getDate(), cd.getHours(), cd.getMinutes(), cd.getSeconds())).map((d) => new _DateTime(d)).value;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
var isDateTime = (dt2) => isDefined(dt2) && dt2 instanceof DateTime;
|
|
133
|
-
var dt = (dt2) => new DateTime(dt2);
|
|
134
|
-
|
|
135
|
-
export {
|
|
136
|
-
DateTime,
|
|
137
|
-
isDateTime,
|
|
138
|
-
dt
|
|
139
|
-
};
|
|
140
|
-
//# sourceMappingURL=chunk-EOHHPAAY.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/domain/DateTime.ts"],"sourcesContent":["import { DateTime as LuxonDateTime, DateTimeUnit as LuxonDateTimeUnit, DurationUnit as LuxonDurationUnit, Settings } from 'luxon';\nimport { Value } from '../types/Value';\nimport { Optional } from '../types/Types';\nimport { choose } from '../types/Case';\nimport { isDefined, isNumber, isString } from '../types/Is';\nimport { isDate } from '../types/IsDate';\nimport { isA } from '../types/IsA';\nimport { ifDefined } from '../utils/If';\nimport { JsonValue } from '../types/Json';\nimport { seconds } from '../utils/Seconds';\nimport { tryTo } from '../types/Try';\nimport { use } from '../types/Constructor';\n\nSettings.defaultZone = 'utc';\n\nexport type DateTimeUnit = LuxonDateTimeUnit;\nexport type DurationUnit = LuxonDurationUnit;\nexport type Duration = Partial<Record<DurationUnit, number>>;\n\nexport type DiffOptions = {\n rounding: 'floor' | 'ceil' | 'round';\n};\n\nexport type DatetimeInput = string | number | Date | DateTime | null;\n\nexport class DateTime extends Value<Optional<string>> {\n protected readonly luxon: LuxonDateTime;\n\n constructor(value?: DatetimeInput);\n constructor(value?: string, format?: string);\n constructor(value?: DatetimeInput, format?: string) {\n const luxon = choose(value)\n .type(isString, v => (format ? LuxonDateTime.fromFormat(v, format, { setZone: true }) : LuxonDateTime.fromISO(v, { setZone: true })))\n .type(isNumber, v => LuxonDateTime.fromMillis(v))\n .type(isDate, v => LuxonDateTime.fromJSDate(v))\n .type(isDateTime, v => v.luxon)\n // Allow constructing with LuxonDateTime without exposing types\n .else(value instanceof LuxonDateTime ? value : LuxonDateTime.fromISO(undefined as any));\n\n super(luxon.toISO() ?? undefined);\n this.luxon = luxon;\n }\n\n static get now(): DateTime {\n return new DateTime(LuxonDateTime.utc() as any);\n }\n\n get isValid(): boolean {\n return isDefined(this.value) && this.utc.isValid;\n }\n\n /**\n * @deprecated Deprecated in favor for DateTime.from as that also accepts locales and another DateTime\n */\n get fromNow(): string {\n return this.from();\n }\n\n get inAmsterdam(): DateTime {\n return this.withZone('Europe/Amsterdam');\n }\n\n get inNewYork(): DateTime {\n return this.withZone('America/New_York');\n }\n\n get inLondon(): DateTime {\n return this.withZone('Europe/London');\n }\n\n get inWarsaw(): DateTime {\n return this.withZone('Europe/Warsaw');\n }\n\n protected get utc(): LuxonDateTime {\n return this.luxon.setZone('utc');\n }\n\n from(locale?: string): string;\n\n from(date?: DateTime, locale?: string): string;\n\n from(dateOrLocale?: string | DateTime, maybeLocale?: string): string {\n return (\n use((isString(dateOrLocale) ? dateOrLocale : maybeLocale) ?? 'en', locale =>\n ifDefined(\n isA<DateTime>(dateOrLocale) ? dateOrLocale : undefined,\n d => this.utc.setLocale(locale).toRelative({ base: d.utc }),\n () => this.utc.setLocale(locale).toRelative()\n )\n ) ?? ''\n );\n }\n\n isAfter(dt: DateTime): boolean {\n return this.utc > dt.utc;\n }\n\n isBefore(dt: DateTime): boolean {\n return this.utc < dt.utc;\n }\n\n equals(dt: DateTime): boolean {\n return this.utc.hasSame(dt.utc, 'millisecond');\n }\n\n add(n: number, unit?: DurationUnit): DateTime;\n\n add(duration: Duration): DateTime;\n\n add(n: number | Duration, unit: DurationUnit = 'day'): DateTime {\n return new DateTime(this.luxon.plus(isNumber(n) ? { [unit]: n } : n) as any);\n }\n\n subtract(n: number, unit?: DurationUnit): DateTime;\n\n subtract(duration: Duration): DateTime;\n\n subtract(n: number | Duration, unit: DurationUnit = 'day'): DateTime {\n return new DateTime(this.luxon.minus(isNumber(n) ? { [unit]: n } : n) as any);\n }\n\n diff(other: DateTime, unit: DateTimeUnit = 'day', opts?: DiffOptions): number {\n return Math[opts?.rounding ?? 'floor'](this.utc.diff(other.utc).as(unit));\n }\n\n startOf(unit: DateTimeUnit = 'day'): DateTime {\n return new DateTime(this.luxon.startOf(unit) as any);\n }\n\n endOf(unit: DateTimeUnit = 'day'): DateTime {\n return new DateTime(this.luxon.endOf(unit) as any);\n }\n\n isWeekend(): boolean {\n return this.luxon.isWeekend;\n }\n\n withZone(zone: string): DateTime {\n return new DateTime(this.luxon.setZone(zone) as any);\n }\n\n toString(): string {\n return this.value ?? '';\n }\n\n toJSON(): JsonValue {\n return this.utc.toISO();\n }\n\n toFormat(format: string): string {\n return this.luxon.toFormat(format);\n }\n\n toLocale(locale = 'nl-NL', format = 'D'): string {\n return this.luxon.setLocale(locale).toFormat(format);\n }\n\n toFull(locale?: string): string {\n return this.toLocale(locale, 'DDD');\n }\n\n toDate(): Optional<Date> {\n return this.isValid ? this.utc.toJSDate() : undefined;\n }\n\n toEpoch(): number {\n return this.luxon.toMillis();\n }\n\n ago(end: DateTime = DateTime.now): string {\n return seconds.toText(end.diff(this, 'second'));\n }\n\n withClock(clock: DateTime): DateTime {\n return tryTo(() => [this.toDate() as Date, clock.toDate() as Date])\n .map(([td, cd]) => new Date(td.getFullYear(), td.getMonth(), td.getDate(), cd.getHours(), cd.getMinutes(), cd.getSeconds()))\n .map(d => new DateTime(d)).value;\n }\n}\n\nexport const isDateTime = (dt?: unknown): dt is DateTime => isDefined(dt) && dt instanceof DateTime;\n\nexport const dt = (dt?: DatetimeInput): DateTime => new DateTime(dt);\n"],"mappings":"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","names":["dt"]}
|
|
File without changes
|