@catbee/utils 2.0.1 → 2.0.3
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/crypto/index.cjs +288 -0
- package/crypto/index.d.ts +230 -3
- package/crypto/index.mjs +283 -2
- package/date/index.cjs +343 -102
- package/date/index.d.ts +178 -6
- package/date/index.mjs +338 -103
- package/logger/index.cjs +1 -1
- package/logger/index.mjs +1 -1
- package/package.json +6 -6
- package/server/index.cjs +175 -11
- package/server/index.d.ts +89 -2
- package/server/index.mjs +177 -13
- package/types/index.d.ts +3 -2
- package/validation/index.cjs +30 -4
- package/validation/index.d.ts +29 -3
- package/validation/index.mjs +30 -5
package/date/index.cjs
CHANGED
|
@@ -28,16 +28,105 @@ var __defProp = Object.defineProperty;
|
|
|
28
28
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
29
29
|
|
|
30
30
|
// src/date/date.utils.ts
|
|
31
|
+
var DATE_FORMAT_PRESETS = {
|
|
32
|
+
short: {
|
|
33
|
+
year: "2-digit",
|
|
34
|
+
month: "numeric",
|
|
35
|
+
day: "numeric",
|
|
36
|
+
hour: "numeric",
|
|
37
|
+
minute: "numeric",
|
|
38
|
+
hour12: true
|
|
39
|
+
},
|
|
40
|
+
medium: {
|
|
41
|
+
year: "numeric",
|
|
42
|
+
month: "short",
|
|
43
|
+
day: "numeric",
|
|
44
|
+
hour: "numeric",
|
|
45
|
+
minute: "numeric",
|
|
46
|
+
second: "numeric",
|
|
47
|
+
hour12: true
|
|
48
|
+
},
|
|
49
|
+
long: {
|
|
50
|
+
year: "numeric",
|
|
51
|
+
month: "long",
|
|
52
|
+
day: "numeric",
|
|
53
|
+
hour: "numeric",
|
|
54
|
+
minute: "numeric",
|
|
55
|
+
second: "numeric",
|
|
56
|
+
hour12: true,
|
|
57
|
+
timeZoneName: "short"
|
|
58
|
+
},
|
|
59
|
+
full: {
|
|
60
|
+
year: "numeric",
|
|
61
|
+
month: "long",
|
|
62
|
+
day: "numeric",
|
|
63
|
+
weekday: "long",
|
|
64
|
+
hour: "numeric",
|
|
65
|
+
minute: "numeric",
|
|
66
|
+
second: "numeric",
|
|
67
|
+
hour12: true,
|
|
68
|
+
timeZoneName: "long"
|
|
69
|
+
},
|
|
70
|
+
shortDate: {
|
|
71
|
+
year: "2-digit",
|
|
72
|
+
month: "numeric",
|
|
73
|
+
day: "numeric"
|
|
74
|
+
},
|
|
75
|
+
mediumDate: {
|
|
76
|
+
year: "numeric",
|
|
77
|
+
month: "short",
|
|
78
|
+
day: "numeric"
|
|
79
|
+
},
|
|
80
|
+
longDate: {
|
|
81
|
+
year: "numeric",
|
|
82
|
+
month: "long",
|
|
83
|
+
day: "numeric"
|
|
84
|
+
},
|
|
85
|
+
fullDate: {
|
|
86
|
+
year: "numeric",
|
|
87
|
+
month: "long",
|
|
88
|
+
day: "numeric",
|
|
89
|
+
weekday: "long"
|
|
90
|
+
},
|
|
91
|
+
shortTime: {
|
|
92
|
+
hour: "numeric",
|
|
93
|
+
minute: "numeric",
|
|
94
|
+
hour12: true
|
|
95
|
+
},
|
|
96
|
+
mediumTime: {
|
|
97
|
+
hour: "numeric",
|
|
98
|
+
minute: "numeric",
|
|
99
|
+
second: "numeric",
|
|
100
|
+
hour12: true
|
|
101
|
+
},
|
|
102
|
+
longTime: {
|
|
103
|
+
hour: "numeric",
|
|
104
|
+
minute: "numeric",
|
|
105
|
+
second: "numeric",
|
|
106
|
+
hour12: true,
|
|
107
|
+
timeZoneName: "short"
|
|
108
|
+
},
|
|
109
|
+
fullTime: {
|
|
110
|
+
hour: "numeric",
|
|
111
|
+
minute: "numeric",
|
|
112
|
+
second: "numeric",
|
|
113
|
+
hour12: true,
|
|
114
|
+
timeZoneName: "long"
|
|
115
|
+
}
|
|
116
|
+
};
|
|
31
117
|
function formatDate(date, options = {}) {
|
|
32
118
|
const { format = "yyyy-MM-dd", locale, timeZone } = options;
|
|
33
119
|
const d = date instanceof Date ? date : new Date(date);
|
|
34
|
-
if (format === "yyyy-MM-dd") {
|
|
120
|
+
if (format === "yyyy-MM-dd" && !timeZone) {
|
|
35
121
|
const yyyy = d.getFullYear();
|
|
36
122
|
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
|
37
123
|
const dd = String(d.getDate()).padStart(2, "0");
|
|
38
124
|
return `${yyyy}-${mm}-${dd}`;
|
|
39
125
|
}
|
|
40
|
-
if (format === "yyyy-MM-dd
|
|
126
|
+
if (format === "yyyy-MM-dd" && timeZone) {
|
|
127
|
+
return formatDateInTimeZone(d, timeZone, "yyyy-MM-dd");
|
|
128
|
+
}
|
|
129
|
+
if (format === "yyyy-MM-dd HH:mm:ss" && !timeZone) {
|
|
41
130
|
const yyyy = d.getFullYear();
|
|
42
131
|
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
|
43
132
|
const dd = String(d.getDate()).padStart(2, "0");
|
|
@@ -46,9 +135,18 @@ function formatDate(date, options = {}) {
|
|
|
46
135
|
const SS = String(d.getSeconds()).padStart(2, "0");
|
|
47
136
|
return `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`;
|
|
48
137
|
}
|
|
138
|
+
if (format === "yyyy-MM-dd HH:mm:ss" && timeZone) {
|
|
139
|
+
return formatDateInTimeZone(d, timeZone, "yyyy-MM-dd HH:mm:ss");
|
|
140
|
+
}
|
|
49
141
|
if (format === "relative") {
|
|
50
142
|
return formatRelativeTime(date);
|
|
51
143
|
}
|
|
144
|
+
if (Object.hasOwn(DATE_FORMAT_PRESETS, format)) {
|
|
145
|
+
return new Intl.DateTimeFormat(locale, {
|
|
146
|
+
...DATE_FORMAT_PRESETS[format],
|
|
147
|
+
timeZone
|
|
148
|
+
}).format(d);
|
|
149
|
+
}
|
|
52
150
|
return new Intl.DateTimeFormat(locale, {
|
|
53
151
|
timeZone,
|
|
54
152
|
year: format.includes("yyyy") || format.includes("y") ? "numeric" : void 0,
|
|
@@ -83,18 +181,12 @@ function formatRelativeTime(date, now = /* @__PURE__ */ new Date(), locale) {
|
|
|
83
181
|
}
|
|
84
182
|
__name(formatRelativeTime, "formatRelativeTime");
|
|
85
183
|
function parseDate(input, fallback) {
|
|
86
|
-
if (typeof input === "number")
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
const date = new Date(input);
|
|
91
|
-
if (Number.isNaN(date.getTime())) {
|
|
92
|
-
return fallback || null;
|
|
93
|
-
}
|
|
94
|
-
return date;
|
|
95
|
-
} catch {
|
|
96
|
-
return fallback || null;
|
|
184
|
+
if (typeof input === "number") return new Date(input);
|
|
185
|
+
if (!/^\d{4}-\d{2}-\d{2}/.test(input)) {
|
|
186
|
+
return fallback ?? null;
|
|
97
187
|
}
|
|
188
|
+
const date = new Date(input.includes("T") ? input : input + "T00:00:00");
|
|
189
|
+
return Number.isNaN(date.getTime()) ? fallback ?? null : date;
|
|
98
190
|
}
|
|
99
191
|
__name(parseDate, "parseDate");
|
|
100
192
|
function dateDiff(date1, date2 = /* @__PURE__ */ new Date(), unit = "days") {
|
|
@@ -110,8 +202,11 @@ function dateDiff(date1, date2 = /* @__PURE__ */ new Date(), unit = "days") {
|
|
|
110
202
|
return diffMs / (1e3 * 60);
|
|
111
203
|
case "hours":
|
|
112
204
|
return diffMs / (1e3 * 60 * 60);
|
|
113
|
-
case "days":
|
|
114
|
-
|
|
205
|
+
case "days": {
|
|
206
|
+
const n1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate());
|
|
207
|
+
const n2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate());
|
|
208
|
+
return Math.round((n1.getTime() - n2.getTime()) / (1e3 * 60 * 60 * 24));
|
|
209
|
+
}
|
|
115
210
|
case "months":
|
|
116
211
|
return (d1.getFullYear() - d2.getFullYear()) * 12 + d1.getMonth() - d2.getMonth();
|
|
117
212
|
case "years":
|
|
@@ -121,114 +216,131 @@ function dateDiff(date1, date2 = /* @__PURE__ */ new Date(), unit = "days") {
|
|
|
121
216
|
}
|
|
122
217
|
}
|
|
123
218
|
__name(dateDiff, "dateDiff");
|
|
124
|
-
function
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
d.
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
d.
|
|
149
|
-
break;
|
|
219
|
+
function dateDiffDaysTZ(d1, d2, tz) {
|
|
220
|
+
const p1 = getTimeZoneParts(d1, tz);
|
|
221
|
+
const p2 = getTimeZoneParts(d2, tz);
|
|
222
|
+
const a = Date.UTC(p1.year, p1.month - 1, p1.day);
|
|
223
|
+
const b = Date.UTC(p2.year, p2.month - 1, p2.day);
|
|
224
|
+
return Math.round((a - b) / 864e5);
|
|
225
|
+
}
|
|
226
|
+
__name(dateDiffDaysTZ, "dateDiffDaysTZ");
|
|
227
|
+
function addToDate(date, amount, unit, options) {
|
|
228
|
+
const d = new Date(date);
|
|
229
|
+
if (unit === "milliseconds") return new Date(d.getTime() + amount);
|
|
230
|
+
if (unit === "seconds") return new Date(d.getTime() + amount * 1e3);
|
|
231
|
+
if (unit === "minutes") return new Date(d.getTime() + amount * 6e4);
|
|
232
|
+
if (unit === "hours") return new Date(d.getTime() + amount * 36e5);
|
|
233
|
+
const tz = options?.timeZone;
|
|
234
|
+
if (!tz) {
|
|
235
|
+
if (unit === "days") return addDays(d, amount);
|
|
236
|
+
if (unit === "months") {
|
|
237
|
+
const targetMonth = d.getMonth() + amount;
|
|
238
|
+
const targetYear = d.getFullYear() + Math.floor(targetMonth / 12);
|
|
239
|
+
const normalizedMonth = (targetMonth % 12 + 12) % 12;
|
|
240
|
+
const day = d.getDate();
|
|
241
|
+
const lastDay = new Date(targetYear, normalizedMonth + 1, 0).getDate();
|
|
242
|
+
const clampedDay = Math.min(day, lastDay);
|
|
243
|
+
return new Date(targetYear, normalizedMonth, clampedDay, d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
|
|
150
244
|
}
|
|
151
|
-
|
|
152
|
-
d.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
245
|
+
if (unit === "years") {
|
|
246
|
+
const targetYear = d.getFullYear() + amount;
|
|
247
|
+
const month = d.getMonth();
|
|
248
|
+
const day = d.getDate();
|
|
249
|
+
const lastDay = new Date(targetYear, month + 1, 0).getDate();
|
|
250
|
+
const clampedDay = Math.min(day, lastDay);
|
|
251
|
+
return new Date(targetYear, month, clampedDay, d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
|
|
252
|
+
}
|
|
253
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
254
|
+
}
|
|
255
|
+
const parts = getTimeZoneParts(d, tz);
|
|
256
|
+
const ms = d.getMilliseconds();
|
|
257
|
+
const result = {
|
|
258
|
+
...parts,
|
|
259
|
+
day: parts.day,
|
|
260
|
+
month: parts.month,
|
|
261
|
+
year: parts.year,
|
|
262
|
+
millisecond: ms
|
|
263
|
+
};
|
|
264
|
+
if (unit === "days") result.day += amount;
|
|
265
|
+
if (unit === "months") {
|
|
266
|
+
result.month += amount;
|
|
267
|
+
result.year += Math.floor((result.month - 1) / 12);
|
|
268
|
+
result.month = ((result.month - 1) % 12 + 12) % 12 + 1;
|
|
269
|
+
const lastDay = new Date(Date.UTC(result.year, result.month, 0)).getUTCDate();
|
|
270
|
+
result.day = Math.min(result.day, lastDay);
|
|
271
|
+
}
|
|
272
|
+
if (unit === "years") {
|
|
273
|
+
result.year += amount;
|
|
274
|
+
const lastDay = new Date(Date.UTC(result.year, result.month, 0)).getUTCDate();
|
|
275
|
+
result.day = Math.min(result.day, lastDay);
|
|
276
|
+
}
|
|
277
|
+
return zonedTimeToUtc(result, tz);
|
|
158
278
|
}
|
|
159
279
|
__name(addToDate, "addToDate");
|
|
280
|
+
function zonedTimeToUtc(parts, timeZone) {
|
|
281
|
+
const utcGuess = new Date(Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour ?? 0, parts.minute ?? 0, parts.second ?? 0));
|
|
282
|
+
const offset1 = getTimezoneOffset(timeZone, utcGuess);
|
|
283
|
+
const adjusted = new Date(utcGuess.getTime() - offset1 * 6e4);
|
|
284
|
+
const offset2 = getTimezoneOffset(timeZone, adjusted);
|
|
285
|
+
const result = offset1 !== offset2 ? new Date(utcGuess.getTime() - offset2 * 6e4) : adjusted;
|
|
286
|
+
if (parts.millisecond !== void 0) {
|
|
287
|
+
result.setMilliseconds(parts.millisecond);
|
|
288
|
+
}
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
__name(zonedTimeToUtc, "zonedTimeToUtc");
|
|
160
292
|
function startOf(date, unit) {
|
|
161
|
-
const d =
|
|
293
|
+
const d = new Date(date);
|
|
162
294
|
switch (unit) {
|
|
163
295
|
case "second":
|
|
164
|
-
d.
|
|
165
|
-
break;
|
|
296
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), 0);
|
|
166
297
|
case "minute":
|
|
167
|
-
d.
|
|
168
|
-
break;
|
|
298
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), 0, 0);
|
|
169
299
|
case "hour":
|
|
170
|
-
d.
|
|
171
|
-
break;
|
|
300
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), 0, 0, 0);
|
|
172
301
|
case "day":
|
|
173
|
-
d.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
d.
|
|
178
|
-
|
|
302
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
303
|
+
case "week": {
|
|
304
|
+
const day = d.getDay();
|
|
305
|
+
const diff = -day;
|
|
306
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate() + diff);
|
|
307
|
+
}
|
|
179
308
|
case "month":
|
|
180
|
-
d.
|
|
181
|
-
d.setHours(0, 0, 0, 0);
|
|
182
|
-
break;
|
|
309
|
+
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
183
310
|
case "quarter":
|
|
184
|
-
d.
|
|
185
|
-
d.setHours(0, 0, 0, 0);
|
|
186
|
-
break;
|
|
311
|
+
return new Date(d.getFullYear(), Math.floor(d.getMonth() / 3) * 3, 1);
|
|
187
312
|
case "year":
|
|
188
|
-
d.
|
|
189
|
-
d.setHours(0, 0, 0, 0);
|
|
190
|
-
break;
|
|
313
|
+
return new Date(d.getFullYear(), 0, 1);
|
|
191
314
|
default:
|
|
192
315
|
throw new Error(`Unsupported unit: ${unit}`);
|
|
193
316
|
}
|
|
194
|
-
return d;
|
|
195
317
|
}
|
|
196
318
|
__name(startOf, "startOf");
|
|
197
319
|
function endOf(date, unit) {
|
|
198
|
-
const d =
|
|
320
|
+
const d = new Date(date);
|
|
199
321
|
switch (unit) {
|
|
200
322
|
case "second":
|
|
201
|
-
d.
|
|
202
|
-
break;
|
|
323
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), 999);
|
|
203
324
|
case "minute":
|
|
204
|
-
d.
|
|
205
|
-
break;
|
|
325
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), 59, 999);
|
|
206
326
|
case "hour":
|
|
207
|
-
d.
|
|
208
|
-
break;
|
|
327
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), 59, 59, 999);
|
|
209
328
|
case "day":
|
|
210
|
-
d.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
d.
|
|
215
|
-
|
|
329
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
|
|
330
|
+
case "week": {
|
|
331
|
+
const day = d.getDay();
|
|
332
|
+
const diff = 6 - day;
|
|
333
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate() + diff, 23, 59, 59, 999);
|
|
334
|
+
}
|
|
216
335
|
case "month":
|
|
217
|
-
d.
|
|
218
|
-
d.setHours(23, 59, 59, 999);
|
|
219
|
-
break;
|
|
336
|
+
return new Date(d.getFullYear(), d.getMonth() + 1, 0, 23, 59, 59, 999);
|
|
220
337
|
case "quarter":
|
|
221
|
-
d.
|
|
222
|
-
d.setHours(23, 59, 59, 999);
|
|
223
|
-
break;
|
|
338
|
+
return new Date(d.getFullYear(), Math.floor(d.getMonth() / 3) * 3 + 3, 0, 23, 59, 59, 999);
|
|
224
339
|
case "year":
|
|
225
|
-
d.
|
|
226
|
-
d.setHours(23, 59, 59, 999);
|
|
227
|
-
break;
|
|
340
|
+
return new Date(d.getFullYear(), 11, 31, 23, 59, 59, 999);
|
|
228
341
|
default:
|
|
229
342
|
throw new Error(`Unsupported unit: ${unit}`);
|
|
230
343
|
}
|
|
231
|
-
return d;
|
|
232
344
|
}
|
|
233
345
|
__name(endOf, "endOf");
|
|
234
346
|
function isBetween(date, start, end, inclusive = true) {
|
|
@@ -347,19 +459,19 @@ function isPast(date) {
|
|
|
347
459
|
}
|
|
348
460
|
__name(isPast, "isPast");
|
|
349
461
|
function addDays(date, days) {
|
|
350
|
-
const d = new Date(date
|
|
462
|
+
const d = new Date(date);
|
|
351
463
|
d.setDate(d.getDate() + days);
|
|
352
464
|
return d;
|
|
353
465
|
}
|
|
354
466
|
__name(addDays, "addDays");
|
|
355
467
|
function addMonths(date, months) {
|
|
356
|
-
const d = new Date(date
|
|
468
|
+
const d = new Date(date);
|
|
357
469
|
d.setMonth(d.getMonth() + months);
|
|
358
470
|
return d;
|
|
359
471
|
}
|
|
360
472
|
__name(addMonths, "addMonths");
|
|
361
473
|
function addYears(date, years) {
|
|
362
|
-
const d = new Date(date
|
|
474
|
+
const d = new Date(date);
|
|
363
475
|
d.setFullYear(d.getFullYear() + years);
|
|
364
476
|
return d;
|
|
365
477
|
}
|
|
@@ -370,13 +482,99 @@ function quarterOf(date) {
|
|
|
370
482
|
}
|
|
371
483
|
__name(quarterOf, "quarterOf");
|
|
372
484
|
function weekOfYear(date) {
|
|
373
|
-
const d =
|
|
374
|
-
d.
|
|
375
|
-
|
|
376
|
-
const yearStart =
|
|
377
|
-
return Math.ceil(((
|
|
485
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
486
|
+
const target = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
|
|
487
|
+
target.setUTCDate(target.getUTCDate() + 4 - (target.getUTCDay() || 7));
|
|
488
|
+
const yearStart = Date.UTC(target.getUTCFullYear(), 0, 1);
|
|
489
|
+
return Math.ceil(((target.getTime() - yearStart) / 864e5 + 1) / 7);
|
|
378
490
|
}
|
|
379
491
|
__name(weekOfYear, "weekOfYear");
|
|
492
|
+
function getTimezoneOffset(timeZone, date = /* @__PURE__ */ new Date()) {
|
|
493
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
494
|
+
const parts = getTimeZoneParts(d, timeZone);
|
|
495
|
+
const tzDate = new Date(Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second));
|
|
496
|
+
return Math.round((tzDate.getTime() - d.getTime()) / 6e4);
|
|
497
|
+
}
|
|
498
|
+
__name(getTimezoneOffset, "getTimezoneOffset");
|
|
499
|
+
function toTimeZone(date, timeZone) {
|
|
500
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
501
|
+
const parts = getTimeZoneParts(d, timeZone);
|
|
502
|
+
return {
|
|
503
|
+
year: parts.year,
|
|
504
|
+
month: parts.month,
|
|
505
|
+
day: parts.day,
|
|
506
|
+
hour: parts.hour,
|
|
507
|
+
minute: parts.minute,
|
|
508
|
+
second: parts.second,
|
|
509
|
+
millisecond: d.getMilliseconds()
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
__name(toTimeZone, "toTimeZone");
|
|
513
|
+
function formatDateInTimeZone(date, timeZone, format = "yyyy-MM-dd HH:mm:ss", locale) {
|
|
514
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
515
|
+
const parts = getTimeZoneParts(d, timeZone);
|
|
516
|
+
if (format === "yyyy-MM-dd") {
|
|
517
|
+
return `${parts.year}-${String(parts.month).padStart(2, "0")}-${String(parts.day).padStart(2, "0")}`;
|
|
518
|
+
}
|
|
519
|
+
if (format === "yyyy-MM-dd HH:mm:ss") {
|
|
520
|
+
return `${parts.year}-${String(parts.month).padStart(2, "0")}-${String(parts.day).padStart(2, "0")} ${String(parts.hour).padStart(2, "0")}:${String(parts.minute).padStart(2, "0")}:${String(parts.second).padStart(2, "0")}`;
|
|
521
|
+
}
|
|
522
|
+
return new Intl.DateTimeFormat(locale, {
|
|
523
|
+
timeZone,
|
|
524
|
+
year: format.includes("yyyy") || format.includes("y") ? "numeric" : void 0,
|
|
525
|
+
month: format.includes("MM") || format.includes("M") ? "numeric" : void 0,
|
|
526
|
+
day: format.includes("dd") || format.includes("d") ? "numeric" : void 0,
|
|
527
|
+
hour: format.includes("HH") || format.includes("H") ? "numeric" : void 0,
|
|
528
|
+
minute: format.includes("mm") || format.includes("m") ? "numeric" : void 0,
|
|
529
|
+
second: format.includes("ss") || format.includes("s") ? "numeric" : void 0,
|
|
530
|
+
hour12: !format.includes("HH") && !format.includes("H")
|
|
531
|
+
}).format(d);
|
|
532
|
+
}
|
|
533
|
+
__name(formatDateInTimeZone, "formatDateInTimeZone");
|
|
534
|
+
function isDST(timeZone, date = /* @__PURE__ */ new Date()) {
|
|
535
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
536
|
+
const year = d.getUTCFullYear();
|
|
537
|
+
const jan = getTimezoneOffset(timeZone, new Date(Date.UTC(year, 0, 15, 12, 0, 0)));
|
|
538
|
+
const jul = getTimezoneOffset(timeZone, new Date(Date.UTC(year, 6, 15, 12, 0, 0)));
|
|
539
|
+
const standardOffset = Math.min(jan, jul);
|
|
540
|
+
return getTimezoneOffset(timeZone, d) > standardOffset;
|
|
541
|
+
}
|
|
542
|
+
__name(isDST, "isDST");
|
|
543
|
+
function getTimezoneAbbreviation(timeZone, date = /* @__PURE__ */ new Date(), locale = "en-US") {
|
|
544
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
545
|
+
const parts = new Intl.DateTimeFormat(locale, {
|
|
546
|
+
timeZone,
|
|
547
|
+
timeZoneName: "short"
|
|
548
|
+
}).formatToParts(d);
|
|
549
|
+
return parts.find((p) => p.type === "timeZoneName")?.value ?? "";
|
|
550
|
+
}
|
|
551
|
+
__name(getTimezoneAbbreviation, "getTimezoneAbbreviation");
|
|
552
|
+
function getTimeZoneParts(date, timeZone) {
|
|
553
|
+
const fmt = new Intl.DateTimeFormat("en-US", {
|
|
554
|
+
timeZone,
|
|
555
|
+
year: "numeric",
|
|
556
|
+
month: "numeric",
|
|
557
|
+
day: "numeric",
|
|
558
|
+
hour: "numeric",
|
|
559
|
+
minute: "numeric",
|
|
560
|
+
second: "numeric",
|
|
561
|
+
hour12: false
|
|
562
|
+
});
|
|
563
|
+
const parts = fmt.formatToParts(date);
|
|
564
|
+
const get = /* @__PURE__ */ __name((type) => {
|
|
565
|
+
const val = parts.find((p) => p.type === type)?.value ?? "0";
|
|
566
|
+
return parseInt(val, 10);
|
|
567
|
+
}, "get");
|
|
568
|
+
return {
|
|
569
|
+
year: get("year"),
|
|
570
|
+
month: get("month"),
|
|
571
|
+
day: get("day"),
|
|
572
|
+
hour: get("hour") === 24 ? 0 : get("hour"),
|
|
573
|
+
minute: get("minute"),
|
|
574
|
+
second: get("second")
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
__name(getTimeZoneParts, "getTimeZoneParts");
|
|
380
578
|
|
|
381
579
|
// src/date/date.builder.ts
|
|
382
580
|
var DateBuilder = class _DateBuilder {
|
|
@@ -942,6 +1140,43 @@ var DateBuilder = class _DateBuilder {
|
|
|
942
1140
|
toString() {
|
|
943
1141
|
return this.date.toString();
|
|
944
1142
|
}
|
|
1143
|
+
// ========== Timezone Methods ==========
|
|
1144
|
+
/**
|
|
1145
|
+
* Format the date in a specific timezone.
|
|
1146
|
+
* @param timeZone - IANA timezone identifier (e.g., 'America/New_York')
|
|
1147
|
+
* @param format - Format pattern (default: 'yyyy-MM-dd HH:mm:ss')
|
|
1148
|
+
*/
|
|
1149
|
+
formatInTimeZone(timeZone, format = "yyyy-MM-dd HH:mm:ss") {
|
|
1150
|
+
return formatDateInTimeZone(this.date, timeZone, format);
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Get the wall-clock components in a specific timezone.
|
|
1154
|
+
* @param timeZone - IANA timezone identifier
|
|
1155
|
+
*/
|
|
1156
|
+
toTimeZone(timeZone) {
|
|
1157
|
+
return toTimeZone(this.date, timeZone);
|
|
1158
|
+
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Get the UTC offset in minutes for a specific timezone at this date's instant.
|
|
1161
|
+
* @param timeZone - IANA timezone identifier
|
|
1162
|
+
*/
|
|
1163
|
+
getTimezoneOffset(timeZone) {
|
|
1164
|
+
return getTimezoneOffset(timeZone, this.date);
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Check if the specified timezone is observing DST at this date's instant.
|
|
1168
|
+
* @param timeZone - IANA timezone identifier
|
|
1169
|
+
*/
|
|
1170
|
+
isDST(timeZone) {
|
|
1171
|
+
return isDST(timeZone, this.date);
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* Get the timezone abbreviation (e.g., 'EST', 'EDT') for a specific timezone.
|
|
1175
|
+
* @param timeZone - IANA timezone identifier
|
|
1176
|
+
*/
|
|
1177
|
+
getTimezoneAbbreviation(timeZone) {
|
|
1178
|
+
return getTimezoneAbbreviation(timeZone, this.date);
|
|
1179
|
+
}
|
|
945
1180
|
};
|
|
946
1181
|
|
|
947
1182
|
exports.DateBuilder = DateBuilder;
|
|
@@ -950,13 +1185,18 @@ exports.addMonths = addMonths;
|
|
|
950
1185
|
exports.addToDate = addToDate;
|
|
951
1186
|
exports.addYears = addYears;
|
|
952
1187
|
exports.dateDiff = dateDiff;
|
|
1188
|
+
exports.dateDiffDaysTZ = dateDiffDaysTZ;
|
|
953
1189
|
exports.daysInMonth = daysInMonth;
|
|
954
1190
|
exports.endOf = endOf;
|
|
955
1191
|
exports.formatDate = formatDate;
|
|
1192
|
+
exports.formatDateInTimeZone = formatDateInTimeZone;
|
|
956
1193
|
exports.formatDuration = formatDuration;
|
|
957
1194
|
exports.formatRelativeTime = formatRelativeTime;
|
|
958
1195
|
exports.getDateFromDuration = getDateFromDuration;
|
|
1196
|
+
exports.getTimezoneAbbreviation = getTimezoneAbbreviation;
|
|
1197
|
+
exports.getTimezoneOffset = getTimezoneOffset;
|
|
959
1198
|
exports.isBetween = isBetween;
|
|
1199
|
+
exports.isDST = isDST;
|
|
960
1200
|
exports.isFuture = isFuture;
|
|
961
1201
|
exports.isLeapYear = isLeapYear;
|
|
962
1202
|
exports.isPast = isPast;
|
|
@@ -966,4 +1206,5 @@ exports.parseDate = parseDate;
|
|
|
966
1206
|
exports.parseDuration = parseDuration;
|
|
967
1207
|
exports.quarterOf = quarterOf;
|
|
968
1208
|
exports.startOf = startOf;
|
|
1209
|
+
exports.toTimeZone = toTimeZone;
|
|
969
1210
|
exports.weekOfYear = weekOfYear;
|