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