one-second 0.0.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/dist/index.js ADDED
@@ -0,0 +1,695 @@
1
+ /**
2
+ * date-lite - Ultra-lightweight date library using native Intl API
3
+ * Zero dependencies, ~2KB, immutable, tree-shakeable
4
+ */
5
+ // ============================================
6
+ // Core: Parse to Date
7
+ // ============================================
8
+ /**
9
+ * Convert any input to a Date object
10
+ */
11
+ export function toDate(input) {
12
+ if (input instanceof Date)
13
+ return new Date(input.getTime());
14
+ if (typeof input === 'number')
15
+ return new Date(input);
16
+ return new Date(input);
17
+ }
18
+ /**
19
+ * Check if input is a valid date
20
+ */
21
+ export function isValid(input) {
22
+ const d = toDate(input);
23
+ return !isNaN(d.getTime());
24
+ }
25
+ // ============================================
26
+ // Formatting (using native Intl)
27
+ // ============================================
28
+ // Cache formatters for performance
29
+ const formatterCache = new Map();
30
+ function getFormatter(options) {
31
+ const key = JSON.stringify(options);
32
+ let formatter = formatterCache.get(key);
33
+ if (!formatter) {
34
+ const { locale, ...opts } = options;
35
+ formatter = new Intl.DateTimeFormat(locale, opts);
36
+ formatterCache.set(key, formatter);
37
+ }
38
+ return formatter;
39
+ }
40
+ /**
41
+ * Format date using Intl.DateTimeFormat
42
+ */
43
+ export function format(input, options = {}) {
44
+ return getFormatter(options).format(toDate(input));
45
+ }
46
+ /**
47
+ * Format date to ISO string (YYYY-MM-DD)
48
+ */
49
+ export function toISO(input) {
50
+ const d = toDate(input);
51
+ const year = d.getFullYear();
52
+ const month = String(d.getMonth() + 1).padStart(2, '0');
53
+ const day = String(d.getDate()).padStart(2, '0');
54
+ return `${year}-${month}-${day}`;
55
+ }
56
+ /**
57
+ * Format time to HH:MM:SS
58
+ */
59
+ export function toTime(input) {
60
+ const d = toDate(input);
61
+ const hours = String(d.getHours()).padStart(2, '0');
62
+ const minutes = String(d.getMinutes()).padStart(2, '0');
63
+ const seconds = String(d.getSeconds()).padStart(2, '0');
64
+ return `${hours}:${minutes}:${seconds}`;
65
+ }
66
+ /**
67
+ * Format to full ISO datetime string
68
+ */
69
+ export function toISOString(input) {
70
+ return toDate(input).toISOString();
71
+ }
72
+ /**
73
+ * Format date using format string (like dayjs/moment)
74
+ * Tokens: YYYY, YY, MM, M, DD, D, HH, H, mm, m, ss, s, SSS, ddd, dddd, MMM, MMMM, A, a
75
+ */
76
+ export function formatStr(input, template, locale = 'en-US') {
77
+ const d = toDate(input);
78
+ const year = d.getFullYear();
79
+ const month = d.getMonth();
80
+ const date = d.getDate();
81
+ const day = d.getDay();
82
+ const hours = d.getHours();
83
+ const minutes = d.getMinutes();
84
+ const seconds = d.getSeconds();
85
+ const ms = d.getMilliseconds();
86
+ // Get localized names using Intl
87
+ const monthLong = new Intl.DateTimeFormat(locale, { month: 'long' }).format(d);
88
+ const monthShort = new Intl.DateTimeFormat(locale, { month: 'short' }).format(d);
89
+ const dayLong = new Intl.DateTimeFormat(locale, { weekday: 'long' }).format(d);
90
+ const dayShort = new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(d);
91
+ const pad = (n, len = 2) => String(n).padStart(len, '0');
92
+ const tokens = {
93
+ 'YYYY': String(year),
94
+ 'YY': String(year).slice(-2),
95
+ 'MMMM': monthLong,
96
+ 'MMM': monthShort,
97
+ 'MM': pad(month + 1),
98
+ 'M': String(month + 1),
99
+ 'DD': pad(date),
100
+ 'D': String(date),
101
+ 'dddd': dayLong,
102
+ 'ddd': dayShort,
103
+ 'HH': pad(hours),
104
+ 'H': String(hours),
105
+ 'hh': pad(hours % 12 || 12),
106
+ 'h': String(hours % 12 || 12),
107
+ 'mm': pad(minutes),
108
+ 'm': String(minutes),
109
+ 'ss': pad(seconds),
110
+ 's': String(seconds),
111
+ 'SSS': pad(ms, 3),
112
+ 'A': hours < 12 ? 'AM' : 'PM',
113
+ 'a': hours < 12 ? 'am' : 'pm',
114
+ };
115
+ // Sort by length (longest first) to match MMMM before MMM before MM before M
116
+ const pattern = Object.keys(tokens)
117
+ .sort((a, b) => b.length - a.length)
118
+ .join('|');
119
+ return template.replace(new RegExp(pattern, 'g'), match => tokens[match] || match);
120
+ }
121
+ /**
122
+ * Parse date from string with format
123
+ * Tokens: YYYY, MM, DD, HH, mm, ss
124
+ */
125
+ export function parse(dateStr, template) {
126
+ const tokenDefs = [
127
+ { token: 'YYYY', regex: '(\\d{4})', field: 'year' },
128
+ { token: 'YY', regex: '(\\d{2})', field: 'year', transform: (v) => 2000 + v },
129
+ { token: 'MM', regex: '(\\d{2})', field: 'month', transform: (v) => v - 1 },
130
+ { token: 'M', regex: '(\\d{1,2})', field: 'month', transform: (v) => v - 1 },
131
+ { token: 'DD', regex: '(\\d{2})', field: 'day' },
132
+ { token: 'D', regex: '(\\d{1,2})', field: 'day' },
133
+ { token: 'HH', regex: '(\\d{2})', field: 'hour' },
134
+ { token: 'H', regex: '(\\d{1,2})', field: 'hour' },
135
+ { token: 'mm', regex: '(\\d{2})', field: 'minute' },
136
+ { token: 'm', regex: '(\\d{1,2})', field: 'minute' },
137
+ { token: 'ss', regex: '(\\d{2})', field: 'second' },
138
+ { token: 's', regex: '(\\d{1,2})', field: 'second' },
139
+ { token: 'SSS', regex: '(\\d{3})', field: 'ms' },
140
+ ];
141
+ // Sort by token length (longest first) to avoid partial matches
142
+ const sortedDefs = [...tokenDefs].sort((a, b) => b.token.length - a.token.length);
143
+ // Find which tokens are in the template and their positions
144
+ const foundTokens = [];
145
+ let searchTemplate = template;
146
+ for (const def of sortedDefs) {
147
+ let pos = searchTemplate.indexOf(def.token);
148
+ while (pos !== -1) {
149
+ foundTokens.push({ pos, def });
150
+ // Replace with placeholder to avoid double-matching
151
+ searchTemplate = searchTemplate.substring(0, pos) + '\x00'.repeat(def.token.length) + searchTemplate.substring(pos + def.token.length);
152
+ pos = searchTemplate.indexOf(def.token);
153
+ }
154
+ }
155
+ // Sort by position
156
+ foundTokens.sort((a, b) => a.pos - b.pos);
157
+ // Build regex pattern
158
+ let pattern = template;
159
+ // Escape special regex chars first
160
+ pattern = pattern.replace(/[.*+?^${}|[\]\\]/g, '\\$&');
161
+ // Replace tokens with their regex patterns (in reverse order to maintain positions)
162
+ for (const { def } of [...foundTokens].reverse().sort((a, b) => b.pos - a.pos)) {
163
+ const escaped = def.token.replace(/[.*+?^${}|[\]\\]/g, '\\$&');
164
+ pattern = pattern.replace(escaped, def.regex);
165
+ }
166
+ const regex = new RegExp('^' + pattern + '$');
167
+ const match = dateStr.match(regex);
168
+ if (!match) {
169
+ return new Date(NaN);
170
+ }
171
+ const parts = {
172
+ year: new Date().getFullYear(),
173
+ month: 0,
174
+ day: 1,
175
+ hour: 0,
176
+ minute: 0,
177
+ second: 0,
178
+ ms: 0,
179
+ };
180
+ // Apply matches in order
181
+ for (let i = 0; i < foundTokens.length; i++) {
182
+ const { def } = foundTokens[i];
183
+ let value = parseInt(match[i + 1], 10);
184
+ if (def.transform) {
185
+ value = def.transform(value);
186
+ }
187
+ parts[def.field] = value;
188
+ }
189
+ return new Date(parts.year, parts.month, parts.day, parts.hour, parts.minute, parts.second, parts.ms);
190
+ }
191
+ // Preset formats
192
+ export function formatDate(input, locale = 'en-US') {
193
+ return format(input, { locale, year: 'numeric', month: 'short', day: 'numeric' });
194
+ }
195
+ export function formatDateTime(input, locale = 'en-US') {
196
+ return format(input, {
197
+ locale,
198
+ year: 'numeric',
199
+ month: 'short',
200
+ day: 'numeric',
201
+ hour: '2-digit',
202
+ minute: '2-digit',
203
+ });
204
+ }
205
+ export function formatTime(input, locale = 'en-US') {
206
+ return format(input, { locale, hour: '2-digit', minute: '2-digit' });
207
+ }
208
+ // ============================================
209
+ // Relative Time (using native Intl.RelativeTimeFormat)
210
+ // ============================================
211
+ const rtfCache = new Map();
212
+ function getRelativeFormatter(options) {
213
+ const key = JSON.stringify(options);
214
+ let formatter = rtfCache.get(key);
215
+ if (!formatter) {
216
+ const { locale = 'en', ...opts } = options;
217
+ formatter = new Intl.RelativeTimeFormat(locale, opts);
218
+ rtfCache.set(key, formatter);
219
+ }
220
+ return formatter;
221
+ }
222
+ /**
223
+ * Get relative time string (e.g., "2 hours ago", "in 3 days")
224
+ */
225
+ export function relative(input, options = {}) {
226
+ const d = toDate(input);
227
+ const now = Date.now();
228
+ const diffMs = d.getTime() - now;
229
+ const diffSec = Math.round(diffMs / 1000);
230
+ const diffMin = Math.round(diffSec / 60);
231
+ const diffHour = Math.round(diffMin / 60);
232
+ const diffDay = Math.round(diffHour / 24);
233
+ const diffWeek = Math.round(diffDay / 7);
234
+ const diffMonth = Math.round(diffDay / 30);
235
+ const diffYear = Math.round(diffDay / 365);
236
+ const rtf = getRelativeFormatter({ numeric: 'auto', ...options });
237
+ if (Math.abs(diffSec) < 60)
238
+ return rtf.format(diffSec, 'second');
239
+ if (Math.abs(diffMin) < 60)
240
+ return rtf.format(diffMin, 'minute');
241
+ if (Math.abs(diffHour) < 24)
242
+ return rtf.format(diffHour, 'hour');
243
+ if (Math.abs(diffDay) < 7)
244
+ return rtf.format(diffDay, 'day');
245
+ if (Math.abs(diffWeek) < 4)
246
+ return rtf.format(diffWeek, 'week');
247
+ if (Math.abs(diffMonth) < 12)
248
+ return rtf.format(diffMonth, 'month');
249
+ return rtf.format(diffYear, 'year');
250
+ }
251
+ /**
252
+ * Get human-readable time ago string
253
+ */
254
+ export function timeAgo(input, locale = 'en') {
255
+ return relative(input, { locale, numeric: 'auto' });
256
+ }
257
+ // ============================================
258
+ // Date Arithmetic (immutable - returns new Date)
259
+ // ============================================
260
+ /**
261
+ * Add time to a date (returns new Date)
262
+ */
263
+ export function add(input, amount, unit) {
264
+ const d = toDate(input);
265
+ switch (unit) {
266
+ case 'year':
267
+ return new Date(d.getFullYear() + amount, d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
268
+ case 'month':
269
+ return new Date(d.getFullYear(), d.getMonth() + amount, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
270
+ case 'week':
271
+ return new Date(d.getTime() + amount * 7 * 24 * 60 * 60 * 1000);
272
+ case 'day':
273
+ return new Date(d.getTime() + amount * 24 * 60 * 60 * 1000);
274
+ case 'hour':
275
+ return new Date(d.getTime() + amount * 60 * 60 * 1000);
276
+ case 'minute':
277
+ return new Date(d.getTime() + amount * 60 * 1000);
278
+ case 'second':
279
+ return new Date(d.getTime() + amount * 1000);
280
+ case 'millisecond':
281
+ return new Date(d.getTime() + amount);
282
+ default:
283
+ return d;
284
+ }
285
+ }
286
+ /**
287
+ * Subtract time from a date (returns new Date)
288
+ */
289
+ export function subtract(input, amount, unit) {
290
+ return add(input, -amount, unit);
291
+ }
292
+ // Convenience methods
293
+ export const addYears = (input, n) => add(input, n, 'year');
294
+ export const addMonths = (input, n) => add(input, n, 'month');
295
+ export const addWeeks = (input, n) => add(input, n, 'week');
296
+ export const addDays = (input, n) => add(input, n, 'day');
297
+ export const addHours = (input, n) => add(input, n, 'hour');
298
+ export const addMinutes = (input, n) => add(input, n, 'minute');
299
+ export const addSeconds = (input, n) => add(input, n, 'second');
300
+ export const subYears = (input, n) => subtract(input, n, 'year');
301
+ export const subMonths = (input, n) => subtract(input, n, 'month');
302
+ export const subWeeks = (input, n) => subtract(input, n, 'week');
303
+ export const subDays = (input, n) => subtract(input, n, 'day');
304
+ export const subHours = (input, n) => subtract(input, n, 'hour');
305
+ export const subMinutes = (input, n) => subtract(input, n, 'minute');
306
+ export const subSeconds = (input, n) => subtract(input, n, 'second');
307
+ // ============================================
308
+ // Comparisons
309
+ // ============================================
310
+ /**
311
+ * Check if two dates are the same day
312
+ */
313
+ export function isSameDay(a, b) {
314
+ const d1 = toDate(a);
315
+ const d2 = toDate(b);
316
+ return d1.getFullYear() === d2.getFullYear() &&
317
+ d1.getMonth() === d2.getMonth() &&
318
+ d1.getDate() === d2.getDate();
319
+ }
320
+ /**
321
+ * Check if two dates are the same month
322
+ */
323
+ export function isSameMonth(a, b) {
324
+ const d1 = toDate(a);
325
+ const d2 = toDate(b);
326
+ return d1.getFullYear() === d2.getFullYear() &&
327
+ d1.getMonth() === d2.getMonth();
328
+ }
329
+ /**
330
+ * Check if two dates are the same year
331
+ */
332
+ export function isSameYear(a, b) {
333
+ return toDate(a).getFullYear() === toDate(b).getFullYear();
334
+ }
335
+ /**
336
+ * Check if date is before another
337
+ */
338
+ export function isBefore(a, b) {
339
+ return toDate(a).getTime() < toDate(b).getTime();
340
+ }
341
+ /**
342
+ * Check if date is after another
343
+ */
344
+ export function isAfter(a, b) {
345
+ return toDate(a).getTime() > toDate(b).getTime();
346
+ }
347
+ /**
348
+ * Check if date is between two dates
349
+ */
350
+ export function isBetween(input, start, end) {
351
+ const t = toDate(input).getTime();
352
+ return t >= toDate(start).getTime() && t <= toDate(end).getTime();
353
+ }
354
+ /**
355
+ * Check if date is today
356
+ */
357
+ export function isToday(input) {
358
+ return isSameDay(input, new Date());
359
+ }
360
+ /**
361
+ * Check if date is yesterday
362
+ */
363
+ export function isYesterday(input) {
364
+ return isSameDay(input, subDays(new Date(), 1));
365
+ }
366
+ /**
367
+ * Check if date is tomorrow
368
+ */
369
+ export function isTomorrow(input) {
370
+ return isSameDay(input, addDays(new Date(), 1));
371
+ }
372
+ /**
373
+ * Check if date is in the past
374
+ */
375
+ export function isPast(input) {
376
+ return toDate(input).getTime() < Date.now();
377
+ }
378
+ /**
379
+ * Check if date is in the future
380
+ */
381
+ export function isFuture(input) {
382
+ return toDate(input).getTime() > Date.now();
383
+ }
384
+ // ============================================
385
+ // Difference
386
+ // ============================================
387
+ /**
388
+ * Get difference between two dates in specified unit
389
+ */
390
+ export function diff(a, b, unit) {
391
+ const d1 = toDate(a);
392
+ const d2 = toDate(b);
393
+ const diffMs = d1.getTime() - d2.getTime();
394
+ switch (unit) {
395
+ case 'year':
396
+ return d1.getFullYear() - d2.getFullYear();
397
+ case 'month':
398
+ return (d1.getFullYear() - d2.getFullYear()) * 12 + (d1.getMonth() - d2.getMonth());
399
+ case 'week':
400
+ return Math.floor(diffMs / (7 * 24 * 60 * 60 * 1000));
401
+ case 'day':
402
+ return Math.floor(diffMs / (24 * 60 * 60 * 1000));
403
+ case 'hour':
404
+ return Math.floor(diffMs / (60 * 60 * 1000));
405
+ case 'minute':
406
+ return Math.floor(diffMs / (60 * 1000));
407
+ case 'second':
408
+ return Math.floor(diffMs / 1000);
409
+ case 'millisecond':
410
+ return diffMs;
411
+ default:
412
+ return diffMs;
413
+ }
414
+ }
415
+ export const diffInYears = (a, b) => diff(a, b, 'year');
416
+ export const diffInMonths = (a, b) => diff(a, b, 'month');
417
+ export const diffInWeeks = (a, b) => diff(a, b, 'week');
418
+ export const diffInDays = (a, b) => diff(a, b, 'day');
419
+ export const diffInHours = (a, b) => diff(a, b, 'hour');
420
+ export const diffInMinutes = (a, b) => diff(a, b, 'minute');
421
+ export const diffInSeconds = (a, b) => diff(a, b, 'second');
422
+ // ============================================
423
+ // Getters
424
+ // ============================================
425
+ export const getYear = (input) => toDate(input).getFullYear();
426
+ export const getMonth = (input) => toDate(input).getMonth(); // 0-indexed
427
+ export const getDate = (input) => toDate(input).getDate();
428
+ export const getDay = (input) => toDate(input).getDay(); // 0 = Sunday
429
+ export const getHours = (input) => toDate(input).getHours();
430
+ export const getMinutes = (input) => toDate(input).getMinutes();
431
+ export const getSeconds = (input) => toDate(input).getSeconds();
432
+ export const getMilliseconds = (input) => toDate(input).getMilliseconds();
433
+ export const getTime = (input) => toDate(input).getTime();
434
+ // ============================================
435
+ // Start/End of Period
436
+ // ============================================
437
+ /**
438
+ * Get start of a time period
439
+ */
440
+ export function startOf(input, unit) {
441
+ const d = toDate(input);
442
+ switch (unit) {
443
+ case 'year':
444
+ return new Date(d.getFullYear(), 0, 1, 0, 0, 0, 0);
445
+ case 'month':
446
+ return new Date(d.getFullYear(), d.getMonth(), 1, 0, 0, 0, 0);
447
+ case 'week': {
448
+ const day = d.getDay();
449
+ const diff = d.getDate() - day;
450
+ return new Date(d.getFullYear(), d.getMonth(), diff, 0, 0, 0, 0);
451
+ }
452
+ case 'day':
453
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
454
+ case 'hour':
455
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), 0, 0, 0);
456
+ case 'minute':
457
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), 0, 0);
458
+ default:
459
+ return d;
460
+ }
461
+ }
462
+ /**
463
+ * Get end of a time period
464
+ */
465
+ export function endOf(input, unit) {
466
+ const d = toDate(input);
467
+ switch (unit) {
468
+ case 'year':
469
+ return new Date(d.getFullYear(), 11, 31, 23, 59, 59, 999);
470
+ case 'month':
471
+ return new Date(d.getFullYear(), d.getMonth() + 1, 0, 23, 59, 59, 999);
472
+ case 'week': {
473
+ const day = d.getDay();
474
+ const diff = d.getDate() + (6 - day);
475
+ return new Date(d.getFullYear(), d.getMonth(), diff, 23, 59, 59, 999);
476
+ }
477
+ case 'day':
478
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
479
+ case 'hour':
480
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), 59, 59, 999);
481
+ case 'minute':
482
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), 59, 999);
483
+ default:
484
+ return d;
485
+ }
486
+ }
487
+ // ============================================
488
+ // Utilities
489
+ // ============================================
490
+ /**
491
+ * Get days in month
492
+ */
493
+ export function daysInMonth(input) {
494
+ const d = toDate(input);
495
+ return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
496
+ }
497
+ /**
498
+ * Check if year is a leap year
499
+ */
500
+ export function isLeapYear(input) {
501
+ const year = toDate(input).getFullYear();
502
+ return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
503
+ }
504
+ /**
505
+ * Get day of year (1-366)
506
+ */
507
+ export function dayOfYear(input) {
508
+ const d = toDate(input);
509
+ const start = new Date(d.getFullYear(), 0, 0);
510
+ const diff = d.getTime() - start.getTime();
511
+ return Math.floor(diff / (24 * 60 * 60 * 1000));
512
+ }
513
+ /**
514
+ * Get week of year
515
+ */
516
+ export function weekOfYear(input) {
517
+ const d = toDate(input);
518
+ const start = new Date(d.getFullYear(), 0, 1);
519
+ const diff = d.getTime() - start.getTime();
520
+ const oneWeek = 7 * 24 * 60 * 60 * 1000;
521
+ return Math.ceil((diff / oneWeek) + 1);
522
+ }
523
+ /**
524
+ * Get quarter (1-4)
525
+ */
526
+ export function quarter(input) {
527
+ return Math.floor(toDate(input).getMonth() / 3) + 1;
528
+ }
529
+ /**
530
+ * Create a date from components
531
+ */
532
+ export function create(year, month = 0, day = 1, hour = 0, minute = 0, second = 0, ms = 0) {
533
+ return new Date(year, month, day, hour, minute, second, ms);
534
+ }
535
+ /**
536
+ * Get current timestamp
537
+ */
538
+ export function now() {
539
+ return Date.now();
540
+ }
541
+ /**
542
+ * Get current date (start of today)
543
+ */
544
+ export function today() {
545
+ return startOf(new Date(), 'day');
546
+ }
547
+ /**
548
+ * Clone a date
549
+ */
550
+ export function clone(input) {
551
+ return toDate(input);
552
+ }
553
+ /**
554
+ * Get min date from array
555
+ */
556
+ export function min(...dates) {
557
+ const timestamps = dates.map(d => toDate(d).getTime());
558
+ return new Date(Math.min(...timestamps));
559
+ }
560
+ /**
561
+ * Get max date from array
562
+ */
563
+ export function max(...dates) {
564
+ const timestamps = dates.map(d => toDate(d).getTime());
565
+ return new Date(Math.max(...timestamps));
566
+ }
567
+ export function duration(amountOrMs, unit) {
568
+ let totalMs;
569
+ if (unit) {
570
+ switch (unit) {
571
+ case 'year':
572
+ totalMs = amountOrMs * 365 * 24 * 60 * 60 * 1000;
573
+ break;
574
+ case 'month':
575
+ totalMs = amountOrMs * 30 * 24 * 60 * 60 * 1000;
576
+ break;
577
+ case 'week':
578
+ totalMs = amountOrMs * 7 * 24 * 60 * 60 * 1000;
579
+ break;
580
+ case 'day':
581
+ totalMs = amountOrMs * 24 * 60 * 60 * 1000;
582
+ break;
583
+ case 'hour':
584
+ totalMs = amountOrMs * 60 * 60 * 1000;
585
+ break;
586
+ case 'minute':
587
+ totalMs = amountOrMs * 60 * 1000;
588
+ break;
589
+ case 'second':
590
+ totalMs = amountOrMs * 1000;
591
+ break;
592
+ case 'millisecond':
593
+ totalMs = amountOrMs;
594
+ break;
595
+ default: totalMs = amountOrMs;
596
+ }
597
+ }
598
+ else {
599
+ totalMs = amountOrMs;
600
+ }
601
+ const absMs = Math.abs(totalMs);
602
+ const years = Math.floor(absMs / (365 * 24 * 60 * 60 * 1000));
603
+ const months = Math.floor((absMs % (365 * 24 * 60 * 60 * 1000)) / (30 * 24 * 60 * 60 * 1000));
604
+ const weeks = Math.floor((absMs % (30 * 24 * 60 * 60 * 1000)) / (7 * 24 * 60 * 60 * 1000));
605
+ const days = Math.floor((absMs % (7 * 24 * 60 * 60 * 1000)) / (24 * 60 * 60 * 1000));
606
+ const hours = Math.floor((absMs % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));
607
+ const minutes = Math.floor((absMs % (60 * 60 * 1000)) / (60 * 1000));
608
+ const seconds = Math.floor((absMs % (60 * 1000)) / 1000);
609
+ const milliseconds = absMs % 1000;
610
+ return {
611
+ years,
612
+ months,
613
+ weeks,
614
+ days,
615
+ hours,
616
+ minutes,
617
+ seconds,
618
+ milliseconds,
619
+ asMilliseconds: () => totalMs,
620
+ asSeconds: () => totalMs / 1000,
621
+ asMinutes: () => totalMs / (60 * 1000),
622
+ asHours: () => totalMs / (60 * 60 * 1000),
623
+ asDays: () => totalMs / (24 * 60 * 60 * 1000),
624
+ asWeeks: () => totalMs / (7 * 24 * 60 * 60 * 1000),
625
+ humanize: (locale = 'en') => {
626
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
627
+ if (years > 0)
628
+ return rtf.format(years, 'year').replace(/^in /, '').replace(/ ago$/, '');
629
+ if (months > 0)
630
+ return rtf.format(months, 'month').replace(/^in /, '').replace(/ ago$/, '');
631
+ if (weeks > 0)
632
+ return rtf.format(weeks, 'week').replace(/^in /, '').replace(/ ago$/, '');
633
+ if (days > 0)
634
+ return rtf.format(days, 'day').replace(/^in /, '').replace(/ ago$/, '');
635
+ if (hours > 0)
636
+ return rtf.format(hours, 'hour').replace(/^in /, '').replace(/ ago$/, '');
637
+ if (minutes > 0)
638
+ return rtf.format(minutes, 'minute').replace(/^in /, '').replace(/ ago$/, '');
639
+ return rtf.format(seconds, 'second').replace(/^in /, '').replace(/ ago$/, '');
640
+ },
641
+ };
642
+ }
643
+ /**
644
+ * Get duration between two dates
645
+ */
646
+ export function durationBetween(a, b) {
647
+ const d1 = toDate(a);
648
+ const d2 = toDate(b);
649
+ return duration(Math.abs(d1.getTime() - d2.getTime()));
650
+ }
651
+ // ============================================
652
+ // UTC support
653
+ // ============================================
654
+ /**
655
+ * Create a UTC date
656
+ */
657
+ export function utc(input) {
658
+ if (!input) {
659
+ return new Date(Date.now());
660
+ }
661
+ const d = toDate(input);
662
+ return new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()));
663
+ }
664
+ /**
665
+ * Get UTC offset in minutes
666
+ */
667
+ export function utcOffset(input) {
668
+ return -toDate(input).getTimezoneOffset();
669
+ }
670
+ /**
671
+ * Check if date is a weekend (Saturday or Sunday)
672
+ */
673
+ export function isWeekend(input) {
674
+ const day = toDate(input).getDay();
675
+ return day === 0 || day === 6;
676
+ }
677
+ /**
678
+ * Check if date is a weekday (Monday-Friday)
679
+ */
680
+ export function isWeekday(input) {
681
+ return !isWeekend(input);
682
+ }
683
+ /**
684
+ * Get the name of the day
685
+ */
686
+ export function dayName(input, locale = 'en-US', style = 'long') {
687
+ return new Intl.DateTimeFormat(locale, { weekday: style }).format(toDate(input));
688
+ }
689
+ /**
690
+ * Get the name of the month
691
+ */
692
+ export function monthName(input, locale = 'en-US', style = 'long') {
693
+ return new Intl.DateTimeFormat(locale, { month: style }).format(toDate(input));
694
+ }
695
+ //# sourceMappingURL=index.js.map