ts-time-utils 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +365 -1
  2. package/dist/age.d.ts +1 -10
  3. package/dist/age.d.ts.map +1 -1
  4. package/dist/constants.d.ts +2 -21
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +12 -13
  7. package/dist/duration.d.ts +171 -0
  8. package/dist/duration.d.ts.map +1 -0
  9. package/dist/duration.js +382 -0
  10. package/dist/esm/age.d.ts +1 -10
  11. package/dist/esm/age.d.ts.map +1 -1
  12. package/dist/esm/constants.d.ts +2 -21
  13. package/dist/esm/constants.d.ts.map +1 -1
  14. package/dist/esm/constants.js +12 -13
  15. package/dist/esm/duration.d.ts +171 -0
  16. package/dist/esm/duration.d.ts.map +1 -0
  17. package/dist/esm/duration.js +382 -0
  18. package/dist/esm/format.d.ts.map +1 -1
  19. package/dist/esm/index.d.ts +10 -6
  20. package/dist/esm/index.d.ts.map +1 -1
  21. package/dist/esm/index.js +8 -0
  22. package/dist/esm/interval.d.ts +3 -6
  23. package/dist/esm/interval.d.ts.map +1 -1
  24. package/dist/esm/locale.d.ts +94 -0
  25. package/dist/esm/locale.d.ts.map +1 -0
  26. package/dist/esm/locale.js +1087 -0
  27. package/dist/esm/performance.d.ts +2 -9
  28. package/dist/esm/performance.d.ts.map +1 -1
  29. package/dist/esm/performance.js +7 -8
  30. package/dist/esm/rangePresets.d.ts +7 -8
  31. package/dist/esm/rangePresets.d.ts.map +1 -1
  32. package/dist/esm/rangePresets.js +11 -9
  33. package/dist/esm/serialize.d.ts +73 -0
  34. package/dist/esm/serialize.d.ts.map +1 -0
  35. package/dist/esm/serialize.js +365 -0
  36. package/dist/esm/timezone.d.ts +2 -6
  37. package/dist/esm/timezone.d.ts.map +1 -1
  38. package/dist/esm/timezone.js +1 -1
  39. package/dist/esm/types.d.ts +229 -0
  40. package/dist/esm/types.d.ts.map +1 -0
  41. package/dist/esm/types.js +25 -0
  42. package/dist/esm/workingHours.d.ts +4 -13
  43. package/dist/esm/workingHours.d.ts.map +1 -1
  44. package/dist/esm/workingHours.js +3 -1
  45. package/dist/format.d.ts.map +1 -1
  46. package/dist/index.d.ts +10 -6
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +8 -0
  49. package/dist/interval.d.ts +3 -6
  50. package/dist/interval.d.ts.map +1 -1
  51. package/dist/locale.d.ts +94 -0
  52. package/dist/locale.d.ts.map +1 -0
  53. package/dist/locale.js +1087 -0
  54. package/dist/performance.d.ts +2 -9
  55. package/dist/performance.d.ts.map +1 -1
  56. package/dist/performance.js +7 -8
  57. package/dist/rangePresets.d.ts +7 -8
  58. package/dist/rangePresets.d.ts.map +1 -1
  59. package/dist/rangePresets.js +11 -9
  60. package/dist/serialize.d.ts +73 -0
  61. package/dist/serialize.d.ts.map +1 -0
  62. package/dist/serialize.js +365 -0
  63. package/dist/timezone.d.ts +2 -6
  64. package/dist/timezone.d.ts.map +1 -1
  65. package/dist/timezone.js +1 -1
  66. package/dist/types.d.ts +229 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +25 -0
  69. package/dist/workingHours.d.ts +4 -13
  70. package/dist/workingHours.d.ts.map +1 -1
  71. package/dist/workingHours.js +3 -1
  72. package/package.json +39 -3
@@ -91,16 +91,9 @@ export declare function measureTime<T>(fn: () => T): [T, number];
91
91
  */
92
92
  export declare function measureAsync<T>(fn: () => Promise<T>): Promise<[T, number]>;
93
93
  /**
94
- * Benchmark result interface
94
+ * Performance measurement and async utilities
95
95
  */
96
- export interface BenchmarkResult {
97
- totalTime: number;
98
- averageTime: number;
99
- minTime: number;
100
- maxTime: number;
101
- iterations: number;
102
- opsPerSecond: number;
103
- }
96
+ import type { BenchmarkResult } from './types.js';
104
97
  /**
105
98
  * Benchmark a function by running it multiple times
106
99
  * @param fn - function to benchmark
@@ -1 +1 @@
1
- {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../src/performance.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,EAAE,EAAE,MAAM,EACV,cAAc,SAAwB,GACrC,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAOlC;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAUlC;AAED;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAC3B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,WAAW,GAAE,MAAU,EACvB,SAAS,GAAE,MAAa,EACxB,QAAQ,GAAE,MAAc,GACvB,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAuB;IAEzC;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,IAAI,IAAI,MAAM;IAed;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,MAAM,IAAI,IAAI;IAQd;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,UAAU,IAAI,MAAM;IAepB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,OAAO;CAGpB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAKvD;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAKhF;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,UAAU,GAAE,MAAa,GAAG,eAAe,CAsBpF"}
1
+ {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../src/performance.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,EAAE,EAAE,MAAM,EACV,cAAc,SAAwB,GACrC,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAOlC;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAUlC;AAED;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAC3B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,WAAW,GAAE,MAAU,EACvB,SAAS,GAAE,MAAa,EACxB,QAAQ,GAAE,MAAc,GACvB,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAuB;IAEzC;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,IAAI,IAAI,MAAM;IAed;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,MAAM,IAAI,IAAI;IAQd;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,UAAU,IAAI,MAAM;IAepB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,OAAO;CAGpB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAKvD;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAKhF;AAED;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,UAAU,GAAE,MAAa,GAAG,eAAe,CAqBpF"}
@@ -207,16 +207,15 @@ export function benchmark(fn, iterations = 1000) {
207
207
  times.push(elapsed);
208
208
  }
209
209
  const totalTime = times.reduce((sum, time) => sum + time, 0);
210
- const averageTime = totalTime / iterations;
211
- const minTime = Math.min(...times);
212
- const maxTime = Math.max(...times);
213
- const opsPerSecond = 1000 / averageTime;
210
+ const average = totalTime / iterations;
211
+ const min = Math.min(...times);
212
+ const max = Math.max(...times);
214
213
  return {
215
214
  totalTime,
216
- averageTime,
217
- minTime,
218
- maxTime,
215
+ average,
216
+ min,
217
+ max,
219
218
  iterations,
220
- opsPerSecond
219
+ total: totalTime
221
220
  };
222
221
  }
@@ -1,8 +1,7 @@
1
- /** Predefined date range helpers (returns [start,end]) */
2
- export interface DateRange {
3
- start: Date;
4
- end: Date;
5
- }
1
+ /**
2
+ * Predefined date range helpers for common time periods
3
+ */
4
+ import type { DateRange } from './types.js';
6
5
  export declare function today(now?: Date): DateRange;
7
6
  export declare function yesterday(now?: Date): DateRange;
8
7
  export declare function tomorrow(now?: Date): DateRange;
@@ -18,9 +17,9 @@ export declare function thisYear(now?: Date): DateRange;
18
17
  export declare function lastYear(now?: Date): DateRange;
19
18
  export declare function nextYear(now?: Date): DateRange;
20
19
  export declare function rollingWindowDays(days: number, now?: Date): DateRange;
21
- export declare function quarterRange(date?: Date): DateRange;
22
- export declare function lastQuarter(date?: Date): DateRange;
23
- export declare function nextQuarter(date?: Date): DateRange;
20
+ export declare function quarterRange(now?: Date): DateRange;
21
+ export declare function lastQuarter(now?: Date): DateRange;
22
+ export declare function nextQuarter(now?: Date): DateRange;
24
23
  /** Map of preset functions for dynamic access */
25
24
  export declare const RANGE_PRESETS: {
26
25
  today: typeof today;
@@ -1 +1 @@
1
- {"version":3,"file":"rangePresets.d.ts","sourceRoot":"","sources":["../src/rangePresets.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAE1D,MAAM,WAAW,SAAS;IAAG,KAAK,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAC;CAAE;AAQtD,wBAAgB,KAAK,CAAC,GAAG,OAAa,GAAG,SAAS,CAA4B;AAC9E,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAKrD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,SAAS,CAIhE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,SAAS,CAIhE;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAOpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAIrD;AAED,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAKrD;AAED,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAKrD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAIpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,SAAS,CAI3E;AAED,wBAAgB,YAAY,CAAC,IAAI,OAAa,GAAG,SAAS,CAKzD;AAED,wBAAgB,WAAW,CAAC,IAAI,OAAa,GAAG,SAAS,CAKxD;AAED,wBAAgB,WAAW,CAAC,IAAI,OAAa,GAAG,SAAS,CAKxD;AAED,iDAAiD;AACjD,eAAO,MAAM,aAAa;;;;sBAEN,IAAI;uBACH,IAAI;sBACL,IAAI;;;;;;;;;;;;;CAKvB,CAAC"}
1
+ {"version":3,"file":"rangePresets.d.ts","sourceRoot":"","sources":["../src/rangePresets.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5C,wBAAgB,KAAK,CAAC,GAAG,OAAa,GAAG,SAAS,CAA4B;AAC9E,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAKrD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,SAAS,CAIhE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,SAAS,CAIhE;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAOpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAIrD;AAED,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAKrD;AAED,wBAAgB,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,CAKrD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAIpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,OAAa,GAAG,SAAS,CAKpD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,SAAS,CAI3E;AAED,wBAAgB,YAAY,CAAC,GAAG,OAAa,GAAG,SAAS,CAKxD;AAED,wBAAgB,WAAW,CAAC,GAAG,OAAa,GAAG,SAAS,CAKvD;AAED,wBAAgB,WAAW,CAAC,GAAG,OAAa,GAAG,SAAS,CAKvD;AAED,iDAAiD;AACjD,eAAO,MAAM,aAAa;;;;sBAEN,IAAI;uBACH,IAAI;sBACL,IAAI;;;;;;;;;;;;;CAKvB,CAAC"}
@@ -1,4 +1,6 @@
1
- /** Predefined date range helpers (returns [start,end]) */
1
+ /**
2
+ * Predefined date range helpers for common time periods
3
+ */
2
4
  function todayRange(now = new Date()) {
3
5
  const start = new Date(now);
4
6
  start.setHours(0, 0, 0, 0);
@@ -93,20 +95,20 @@ export function rollingWindowDays(days, now = new Date()) {
93
95
  start.setDate(start.getDate() - days);
94
96
  return { start, end };
95
97
  }
96
- export function quarterRange(date = new Date()) {
97
- const q = Math.floor(date.getMonth() / 3); // 0-3
98
- const start = new Date(date.getFullYear(), q * 3, 1);
99
- const end = new Date(date.getFullYear(), q * 3 + 3, 1);
98
+ export function quarterRange(now = new Date()) {
99
+ const q = Math.floor(now.getMonth() / 3); // 0-3
100
+ const start = new Date(now.getFullYear(), q * 3, 1);
101
+ const end = new Date(now.getFullYear(), q * 3 + 3, 1);
100
102
  return { start, end };
101
103
  }
102
- export function lastQuarter(date = new Date()) {
103
- const q = quarterRange(date);
104
+ export function lastQuarter(now = new Date()) {
105
+ const q = quarterRange(now);
104
106
  q.start.setMonth(q.start.getMonth() - 3);
105
107
  q.end.setMonth(q.end.getMonth() - 3);
106
108
  return q;
107
109
  }
108
- export function nextQuarter(date = new Date()) {
109
- const q = quarterRange(date);
110
+ export function nextQuarter(now = new Date()) {
111
+ const q = quarterRange(now);
110
112
  q.start.setMonth(q.start.getMonth() + 3);
111
113
  q.end.setMonth(q.end.getMonth() + 3);
112
114
  return q;
@@ -0,0 +1,73 @@
1
+ import type { DateInput, SerializationOptions, DateObject, EpochTimestamp } from './types.js';
2
+ /**
3
+ * Safe JSON date serialization and deserialization utilities
4
+ */
5
+ /**
6
+ * Safely serialize a date to JSON with various format options
7
+ */
8
+ export declare function serializeDate(date: DateInput, options?: SerializationOptions): string | number | DateObject;
9
+ /**
10
+ * Safely deserialize a date from various formats
11
+ */
12
+ export declare function deserializeDate(serializedDate: string | number | DateObject, options?: SerializationOptions): Date | null;
13
+ /**
14
+ * Create a safe JSON reviver function for automatic date parsing
15
+ */
16
+ export declare function createDateReviver(dateKeys?: string[], options?: SerializationOptions): (key: string, value: any) => any;
17
+ /**
18
+ * Create a safe JSON replacer function for automatic date serialization
19
+ */
20
+ export declare function createDateReplacer(dateKeys?: string[], options?: SerializationOptions): (key: string, value: any) => any;
21
+ /**
22
+ * Parse ISO string with better error handling
23
+ */
24
+ export declare function parseISOString(isoString: string, useUTC?: boolean): Date | null;
25
+ /**
26
+ * Convert date to epoch timestamp with specified precision
27
+ */
28
+ export declare function toEpochTimestamp(date: DateInput, precision?: 'milliseconds' | 'seconds' | 'microseconds'): number;
29
+ /**
30
+ * Create date from epoch timestamp with specified precision
31
+ */
32
+ export declare function fromEpochTimestamp(timestamp: number, precision?: 'milliseconds' | 'seconds' | 'microseconds'): Date;
33
+ /**
34
+ * Create epoch timestamp with metadata
35
+ */
36
+ export declare function createEpochTimestamp(date: DateInput, precision?: 'milliseconds' | 'seconds' | 'microseconds', timezone?: string): EpochTimestamp;
37
+ /**
38
+ * Convert date to safe object representation
39
+ */
40
+ export declare function toDateObject(date: DateInput, includeTimezone?: boolean): DateObject;
41
+ /**
42
+ * Create date from object representation
43
+ */
44
+ export declare function fromDateObject(dateObj: DateObject): Date;
45
+ /**
46
+ * Check if a string is a valid ISO date string for serialization
47
+ */
48
+ export declare function isValidISODateString(dateString: string): boolean;
49
+ /**
50
+ * Check if a number is a valid epoch timestamp
51
+ */
52
+ export declare function isValidEpochTimestamp(timestamp: number, precision?: 'milliseconds' | 'seconds' | 'microseconds'): boolean;
53
+ /**
54
+ * Clone a date safely (avoids reference issues)
55
+ */
56
+ export declare function cloneDate(date: DateInput): Date | null;
57
+ /**
58
+ * Compare two dates for equality (ignoring milliseconds if specified)
59
+ */
60
+ export declare function datesEqual(date1: DateInput, date2: DateInput, precision?: 'milliseconds' | 'seconds' | 'minutes'): boolean;
61
+ /**
62
+ * Get current timestamp in various formats
63
+ */
64
+ export declare function now(format?: 'date' | 'iso' | 'epoch-ms' | 'epoch-s'): Date | string | number;
65
+ /**
66
+ * Safely handle JSON parsing with date conversion
67
+ */
68
+ export declare function parseJSONWithDates(jsonString: string, dateKeys?: string[], options?: SerializationOptions): any;
69
+ /**
70
+ * Safely handle JSON stringification with date conversion
71
+ */
72
+ export declare function stringifyWithDates(obj: any, dateKeys?: string[], options?: SerializationOptions, space?: string | number): string;
73
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../src/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9F;;GAEG;AAEH;;GAEG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,OAAO,GAAE,oBAAyB,GACjC,MAAM,GAAG,MAAM,GAAG,UAAU,CAmC9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,EAC5C,OAAO,GAAE,oBAAyB,GACjC,IAAI,GAAG,IAAI,CA2Bb;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,GAAE,MAAM,EAAoD,EACpE,OAAO,GAAE,oBAAyB,GACjC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,GAAG,CAQlC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,GAAE,MAAM,EAAoD,EACpE,OAAO,GAAE,oBAAyB,GACjC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,GAAG,CAgBlC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,OAAe,GAAG,IAAI,GAAG,IAAI,CA4BtF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,GAAE,cAAc,GAAG,SAAS,GAAG,cAA+B,GAAG,MAAM,CAiBjI;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,cAAc,GAAG,SAAS,GAAG,cAA+B,GACtE,IAAI,CAiBN;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EACf,SAAS,GAAE,cAAc,GAAG,SAAS,GAAG,cAA+B,EACvE,QAAQ,CAAC,EAAE,MAAM,GAChB,cAAc,CAMhB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,GAAE,OAAe,GAAG,UAAU,CA0B1F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAsCxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAOhE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,cAAc,GAAG,SAAS,GAAG,cAA+B,GAAG,OAAO,CA0BzI;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAGtD;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,SAAS,EAChB,SAAS,GAAE,cAAc,GAAG,SAAS,GAAG,SAA0B,GACjE,OAAO,CAuBT;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,SAAkB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAcpG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,GAAG,CAML;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,GAAG,EACR,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAMR"}
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Safe JSON date serialization and deserialization utilities
3
+ */
4
+ /**
5
+ * Safely serialize a date to JSON with various format options
6
+ */
7
+ export function serializeDate(date, options = {}) {
8
+ const { format = 'iso', includeTimezone = false, useUTC = false, precision = 'milliseconds', customFormat } = options;
9
+ const dateObj = normalizeDate(date);
10
+ if (!dateObj) {
11
+ throw new Error('Invalid date provided for serialization');
12
+ }
13
+ const workingDate = useUTC ? new Date(dateObj.getTime()) : dateObj;
14
+ switch (format) {
15
+ case 'iso':
16
+ return workingDate.toISOString();
17
+ case 'epoch':
18
+ return toEpochTimestamp(workingDate, precision);
19
+ case 'object':
20
+ return toDateObject(workingDate, includeTimezone);
21
+ case 'custom':
22
+ if (!customFormat) {
23
+ throw new Error('Custom format string required when format is "custom"');
24
+ }
25
+ return formatCustom(workingDate, customFormat);
26
+ default:
27
+ return workingDate.toISOString();
28
+ }
29
+ }
30
+ /**
31
+ * Safely deserialize a date from various formats
32
+ */
33
+ export function deserializeDate(serializedDate, options = {}) {
34
+ const { useUTC = false } = options;
35
+ try {
36
+ if (typeof serializedDate === 'string') {
37
+ return parseISOString(serializedDate, useUTC);
38
+ }
39
+ if (typeof serializedDate === 'number') {
40
+ if (isNaN(serializedDate)) {
41
+ return null;
42
+ }
43
+ return fromEpochTimestamp(serializedDate, options.precision || 'milliseconds');
44
+ }
45
+ if (typeof serializedDate === 'object' && serializedDate !== null) {
46
+ try {
47
+ return fromDateObject(serializedDate);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ return null;
54
+ }
55
+ catch (error) {
56
+ return null;
57
+ }
58
+ }
59
+ /**
60
+ * Create a safe JSON reviver function for automatic date parsing
61
+ */
62
+ export function createDateReviver(dateKeys = ['createdAt', 'updatedAt', 'date', 'timestamp'], options = {}) {
63
+ return (key, value) => {
64
+ if (dateKeys.includes(key) && (typeof value === 'string' || typeof value === 'number')) {
65
+ const parsed = deserializeDate(value, options);
66
+ return parsed || value; // Return original value if parsing fails
67
+ }
68
+ return value;
69
+ };
70
+ }
71
+ /**
72
+ * Create a safe JSON replacer function for automatic date serialization
73
+ */
74
+ export function createDateReplacer(dateKeys = ['createdAt', 'updatedAt', 'date', 'timestamp'], options = {}) {
75
+ return (key, value) => {
76
+ if (dateKeys.includes(key)) {
77
+ if (value instanceof Date) {
78
+ return serializeDate(value, options);
79
+ }
80
+ // Handle case where Date was already converted to ISO string by JSON.stringify
81
+ if (typeof value === 'string' && isValidISODateString(value)) {
82
+ const date = parseISOString(value);
83
+ if (date) {
84
+ return serializeDate(date, options);
85
+ }
86
+ }
87
+ }
88
+ return value;
89
+ };
90
+ }
91
+ /**
92
+ * Parse ISO string with better error handling
93
+ */
94
+ export function parseISOString(isoString, useUTC = false) {
95
+ if (!isoString || typeof isoString !== 'string') {
96
+ return null;
97
+ }
98
+ // Handle various ISO formats
99
+ const cleanedString = isoString.trim();
100
+ // Check for valid ISO format
101
+ const isoRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/;
102
+ if (!isoRegex.test(cleanedString)) {
103
+ // Try to parse anyway, but be more forgiving
104
+ const relaxedRegex = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})?)?$/;
105
+ if (!relaxedRegex.test(cleanedString)) {
106
+ return null;
107
+ }
108
+ }
109
+ try {
110
+ const date = new Date(cleanedString);
111
+ if (isNaN(date.getTime())) {
112
+ return null;
113
+ }
114
+ return useUTC ? new Date(date.getTime() + (date.getTimezoneOffset() * 60000)) : date;
115
+ }
116
+ catch {
117
+ return null;
118
+ }
119
+ }
120
+ /**
121
+ * Convert date to epoch timestamp with specified precision
122
+ */
123
+ export function toEpochTimestamp(date, precision = 'milliseconds') {
124
+ const dateObj = normalizeDate(date);
125
+ if (!dateObj) {
126
+ throw new Error('Invalid date provided for epoch conversion');
127
+ }
128
+ const ms = dateObj.getTime();
129
+ switch (precision) {
130
+ case 'seconds':
131
+ return Math.floor(ms / 1000);
132
+ case 'microseconds':
133
+ return ms * 1000; // JavaScript doesn't have true microsecond precision
134
+ case 'milliseconds':
135
+ default:
136
+ return ms;
137
+ }
138
+ }
139
+ /**
140
+ * Create date from epoch timestamp with specified precision
141
+ */
142
+ export function fromEpochTimestamp(timestamp, precision = 'milliseconds') {
143
+ let ms;
144
+ switch (precision) {
145
+ case 'seconds':
146
+ ms = timestamp * 1000;
147
+ break;
148
+ case 'microseconds':
149
+ ms = timestamp / 1000;
150
+ break;
151
+ case 'milliseconds':
152
+ default:
153
+ ms = timestamp;
154
+ break;
155
+ }
156
+ return new Date(ms);
157
+ }
158
+ /**
159
+ * Create epoch timestamp with metadata
160
+ */
161
+ export function createEpochTimestamp(date, precision = 'milliseconds', timezone) {
162
+ return {
163
+ timestamp: toEpochTimestamp(date, precision),
164
+ precision,
165
+ timezone
166
+ };
167
+ }
168
+ /**
169
+ * Convert date to safe object representation
170
+ */
171
+ export function toDateObject(date, includeTimezone = false) {
172
+ const dateObj = normalizeDate(date);
173
+ if (!dateObj) {
174
+ throw new Error('Invalid date provided for object conversion');
175
+ }
176
+ const obj = {
177
+ year: dateObj.getUTCFullYear(),
178
+ month: dateObj.getUTCMonth() + 1, // Convert to 1-12
179
+ day: dateObj.getUTCDate(),
180
+ hour: dateObj.getUTCHours(),
181
+ minute: dateObj.getUTCMinutes(),
182
+ second: dateObj.getUTCSeconds(),
183
+ millisecond: dateObj.getUTCMilliseconds()
184
+ };
185
+ if (includeTimezone) {
186
+ // Get timezone offset in minutes and convert to string format
187
+ const offset = dateObj.getTimezoneOffset();
188
+ const hours = Math.floor(Math.abs(offset) / 60);
189
+ const minutes = Math.abs(offset) % 60;
190
+ const sign = offset <= 0 ? '+' : '-';
191
+ obj.timezone = `${sign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
192
+ }
193
+ return obj;
194
+ }
195
+ /**
196
+ * Create date from object representation
197
+ */
198
+ export function fromDateObject(dateObj) {
199
+ // Validate required fields
200
+ if (!dateObj || typeof dateObj !== 'object') {
201
+ throw new Error('Invalid date object provided');
202
+ }
203
+ const { year, month, day, hour = 0, minute = 0, second = 0, millisecond = 0 } = dateObj;
204
+ if (!year || !month || !day) {
205
+ throw new Error('Date object must include year, month, and day');
206
+ }
207
+ // Validate ranges
208
+ if (month < 1 || month > 12) {
209
+ throw new Error('Month must be between 1 and 12');
210
+ }
211
+ if (day < 1 || day > 31) {
212
+ throw new Error('Day must be between 1 and 31');
213
+ }
214
+ if (hour < 0 || hour > 23) {
215
+ throw new Error('Hour must be between 0 and 23');
216
+ }
217
+ if (minute < 0 || minute > 59) {
218
+ throw new Error('Minute must be between 0 and 59');
219
+ }
220
+ if (second < 0 || second > 59) {
221
+ throw new Error('Second must be between 0 and 59');
222
+ }
223
+ if (millisecond < 0 || millisecond > 999) {
224
+ throw new Error('Millisecond must be between 0 and 999');
225
+ }
226
+ return new Date(Date.UTC(year, month - 1, day, hour, minute, second, millisecond));
227
+ }
228
+ /**
229
+ * Check if a string is a valid ISO date string for serialization
230
+ */
231
+ export function isValidISODateString(dateString) {
232
+ if (!dateString || typeof dateString !== 'string') {
233
+ return false;
234
+ }
235
+ const parsed = parseISOString(dateString);
236
+ return parsed !== null;
237
+ }
238
+ /**
239
+ * Check if a number is a valid epoch timestamp
240
+ */
241
+ export function isValidEpochTimestamp(timestamp, precision = 'milliseconds') {
242
+ if (typeof timestamp !== 'number' || isNaN(timestamp)) {
243
+ return false;
244
+ }
245
+ // Check reasonable bounds for timestamps
246
+ const now = Date.now();
247
+ let min, max;
248
+ switch (precision) {
249
+ case 'seconds':
250
+ min = 0; // Jan 1, 1970
251
+ max = Math.floor(now / 1000) + (50 * 365 * 24 * 60 * 60); // 50 years from now
252
+ break;
253
+ case 'microseconds':
254
+ min = 0;
255
+ max = now * 1000 + (50 * 365 * 24 * 60 * 60 * 1000 * 1000); // 50 years from now
256
+ break;
257
+ case 'milliseconds':
258
+ default:
259
+ min = 0; // Jan 1, 1970
260
+ max = now + (50 * 365 * 24 * 60 * 60 * 1000); // 50 years from now
261
+ break;
262
+ }
263
+ return timestamp >= min && timestamp <= max;
264
+ }
265
+ /**
266
+ * Clone a date safely (avoids reference issues)
267
+ */
268
+ export function cloneDate(date) {
269
+ const dateObj = normalizeDate(date);
270
+ return dateObj ? new Date(dateObj.getTime()) : null;
271
+ }
272
+ /**
273
+ * Compare two dates for equality (ignoring milliseconds if specified)
274
+ */
275
+ export function datesEqual(date1, date2, precision = 'milliseconds') {
276
+ const d1 = normalizeDate(date1);
277
+ const d2 = normalizeDate(date2);
278
+ if (!d1 || !d2) {
279
+ return false;
280
+ }
281
+ let time1 = d1.getTime();
282
+ let time2 = d2.getTime();
283
+ switch (precision) {
284
+ case 'seconds':
285
+ time1 = Math.floor(time1 / 1000);
286
+ time2 = Math.floor(time2 / 1000);
287
+ break;
288
+ case 'minutes':
289
+ time1 = Math.floor(time1 / 60000);
290
+ time2 = Math.floor(time2 / 60000);
291
+ break;
292
+ }
293
+ return time1 === time2;
294
+ }
295
+ /**
296
+ * Get current timestamp in various formats
297
+ */
298
+ export function now(format = 'date') {
299
+ const current = new Date();
300
+ switch (format) {
301
+ case 'iso':
302
+ return current.toISOString();
303
+ case 'epoch-ms':
304
+ return current.getTime();
305
+ case 'epoch-s':
306
+ return Math.floor(current.getTime() / 1000);
307
+ case 'date':
308
+ default:
309
+ return current;
310
+ }
311
+ }
312
+ /**
313
+ * Safely handle JSON parsing with date conversion
314
+ */
315
+ export function parseJSONWithDates(jsonString, dateKeys, options) {
316
+ try {
317
+ return JSON.parse(jsonString, createDateReviver(dateKeys, options));
318
+ }
319
+ catch (error) {
320
+ throw new Error(`Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
321
+ }
322
+ }
323
+ /**
324
+ * Safely handle JSON stringification with date conversion
325
+ */
326
+ export function stringifyWithDates(obj, dateKeys, options, space) {
327
+ try {
328
+ return JSON.stringify(obj, createDateReplacer(dateKeys, options), space);
329
+ }
330
+ catch (error) {
331
+ throw new Error(`Failed to stringify JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
332
+ }
333
+ }
334
+ // Helper functions
335
+ function normalizeDate(date) {
336
+ if (date instanceof Date) {
337
+ return isNaN(date.getTime()) ? null : date;
338
+ }
339
+ if (typeof date === 'string') {
340
+ const parsed = new Date(date);
341
+ return isNaN(parsed.getTime()) ? null : parsed;
342
+ }
343
+ if (typeof date === 'number') {
344
+ const parsed = new Date(date);
345
+ return isNaN(parsed.getTime()) ? null : parsed;
346
+ }
347
+ return null;
348
+ }
349
+ function formatCustom(date, format) {
350
+ // Simple custom formatter - can be extended
351
+ const formatMap = {
352
+ 'YYYY': date.getUTCFullYear().toString(),
353
+ 'MM': (date.getUTCMonth() + 1).toString().padStart(2, '0'),
354
+ 'DD': date.getUTCDate().toString().padStart(2, '0'),
355
+ 'HH': date.getUTCHours().toString().padStart(2, '0'),
356
+ 'mm': date.getUTCMinutes().toString().padStart(2, '0'),
357
+ 'ss': date.getUTCSeconds().toString().padStart(2, '0'),
358
+ 'SSS': date.getUTCMilliseconds().toString().padStart(3, '0')
359
+ };
360
+ let result = format;
361
+ for (const [token, value] of Object.entries(formatMap)) {
362
+ result = result.replace(new RegExp(token, 'g'), value);
363
+ }
364
+ return result;
365
+ }
@@ -1,11 +1,7 @@
1
1
  /**
2
- * Timezone utilities (rely on Intl API, fallbacks where possible)
2
+ * Timezone utilities using Intl API with fallbacks
3
3
  */
4
- export interface ZonedTime {
5
- date: Date;
6
- zone: string;
7
- offsetMinutes: number;
8
- }
4
+ import type { ZonedTime } from './types.js';
9
5
  /** Get offset (minutes) for a zone at a given date */
10
6
  export declare function getTimezoneOffset(zone: string, date?: Date): number | null;
11
7
  /** Format date/time in a zone */
@@ -1 +1 @@
1
- {"version":3,"file":"timezone.d.ts","sourceRoot":"","sources":["../src/timezone.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,sDAAsD;AACtD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAgBtF;AAED,iCAAiC;AACjC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,qBAA0B,GAAG,MAAM,CAG3G;AAED,yCAAyC;AACzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAIvE;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE,GAAG,IAAI,CAoB9J;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,UAK5B,CAAC;AAEF,0CAA0C;AAC1C,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAKvG;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAI7E"}
1
+ {"version":3,"file":"timezone.d.ts","sourceRoot":"","sources":["../src/timezone.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,sDAAsD;AACtD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAgBtF;AAED,iCAAiC;AACjC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,qBAA0B,GAAG,MAAM,CAG3G;AAED,yCAAyC;AACzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAIvE;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE,GAAG,IAAI,CAoB9J;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,UAK5B,CAAC;AAEF,0CAA0C;AAC1C,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAKvG;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAI7E"}
package/dist/timezone.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Timezone utilities (rely on Intl API, fallbacks where possible)
2
+ * Timezone utilities using Intl API with fallbacks
3
3
  */
4
4
  /** Get offset (minutes) for a zone at a given date */
5
5
  export function getTimezoneOffset(zone, date = new Date()) {