ts-time-utils 4.1.0 → 4.4.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 (61) hide show
  1. package/README.md +81 -31
  2. package/dist/{age.js → age.cjs} +14 -6
  3. package/dist/{calculate.js → calculate.cjs} +30 -18
  4. package/dist/{calendar.js → calendar.cjs} +80 -39
  5. package/dist/{calendars.js → calendars.cjs} +48 -23
  6. package/dist/{chain.js → chain.cjs} +41 -40
  7. package/dist/{compare.js → compare.cjs} +58 -28
  8. package/dist/constants.cjs +19 -0
  9. package/dist/{countdown.js → countdown.cjs} +16 -7
  10. package/dist/{cron.js → cron.cjs} +20 -9
  11. package/dist/{dateRange.js → dateRange.cjs} +42 -26
  12. package/dist/{duration.js → duration.cjs} +56 -44
  13. package/dist/esm/chain.js +0 -5
  14. package/dist/esm/naturalLanguage.d.ts +1 -3
  15. package/dist/esm/naturalLanguage.d.ts.map +1 -1
  16. package/dist/esm/naturalLanguage.js +9 -2
  17. package/dist/esm/plugins.d.ts +0 -6
  18. package/dist/esm/plugins.d.ts.map +1 -1
  19. package/dist/esm/plugins.js +36 -42
  20. package/dist/esm/recurrence.d.ts.map +1 -1
  21. package/dist/esm/recurrence.js +3 -5
  22. package/dist/esm/timezone.d.ts +6 -1
  23. package/dist/esm/timezone.d.ts.map +1 -1
  24. package/dist/esm/timezone.js +106 -66
  25. package/dist/esm/types.d.ts +0 -4
  26. package/dist/esm/types.d.ts.map +1 -1
  27. package/dist/{finance.js → finance.cjs} +39 -22
  28. package/dist/{fiscal.js → fiscal.cjs} +36 -17
  29. package/dist/{format.js → format.cjs} +83 -70
  30. package/dist/{healthcare.js → healthcare.cjs} +37 -22
  31. package/dist/{holidays.js → holidays.cjs} +52 -25
  32. package/dist/index.cjs +595 -0
  33. package/dist/{interval.js → interval.cjs} +24 -11
  34. package/dist/{iterate.js → iterate.cjs} +84 -41
  35. package/dist/{locale.js → locale.cjs} +54 -26
  36. package/dist/{naturalLanguage.js → naturalLanguage.cjs} +36 -23
  37. package/dist/naturalLanguage.d.ts +1 -3
  38. package/dist/naturalLanguage.d.ts.map +1 -1
  39. package/dist/{parse.js → parse.cjs} +24 -11
  40. package/dist/{performance.js → performance.cjs} +23 -10
  41. package/dist/{plugins.js → plugins.cjs} +48 -47
  42. package/dist/plugins.d.ts +0 -6
  43. package/dist/plugins.d.ts.map +1 -1
  44. package/dist/{precision.js → precision.cjs} +74 -37
  45. package/dist/{rangePresets.js → rangePresets.cjs} +40 -19
  46. package/dist/{recurrence.js → recurrence.cjs} +27 -21
  47. package/dist/recurrence.d.ts.map +1 -1
  48. package/dist/{scheduling.js → scheduling.cjs} +46 -31
  49. package/dist/{serialize.js → serialize.cjs} +36 -17
  50. package/dist/{temporal.js → temporal.cjs} +28 -13
  51. package/dist/{timezone.js → timezone.cjs} +140 -82
  52. package/dist/timezone.d.ts +6 -1
  53. package/dist/timezone.d.ts.map +1 -1
  54. package/dist/{types.js → types.cjs} +9 -3
  55. package/dist/types.d.ts +0 -4
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/{validate.js → validate.cjs} +54 -26
  58. package/dist/{workingHours.js → workingHours.cjs} +36 -17
  59. package/package.json +40 -37
  60. package/dist/constants.js +0 -16
  61. package/dist/index.js +0 -72
@@ -19,38 +19,20 @@
19
19
  * chain(new Date()).nextMonday().format('YYYY-MM-DD');
20
20
  * ```
21
21
  */
22
- // Import ChainedDate class directly - safe because chain.js doesn't import plugins.js
23
- // We need the actual class (not just the type) to modify its prototype
24
- let ChainedDateConstructor = null;
22
+ import { ChainedDate } from './chain.js';
25
23
  /**
26
- * Get ChainedDate class lazily to ensure it's fully initialized
24
+ * Get ChainedDate class for prototype mutation.
25
+ * Importing `plugins` now brings in `chain` directly, so the class is available
26
+ * without a hidden global handshake.
27
27
  */
28
28
  function getChainedDate() {
29
- if (!ChainedDateConstructor) {
30
- // Use dynamic import that works in both CJS and ESM
31
- try {
32
- // Try ESM import path first
33
- ChainedDateConstructor = globalThis.__chainedDateClass;
34
- if (!ChainedDateConstructor) {
35
- // Fallback: The class will be set by chain.js when it loads
36
- throw new Error('ChainedDate not yet loaded. Import chain.js before using plugins.');
37
- }
38
- }
39
- catch (e) {
40
- throw new Error('ChainedDate class not available. Ensure chain.js is imported before registering plugins.');
41
- }
29
+ if (!ChainedDate) {
30
+ throw new Error('ChainedDate export is not available yet. Import chain.js before registering plugins.');
42
31
  }
43
- return ChainedDateConstructor;
44
- }
45
- /**
46
- * Initialize the plugin system with ChainedDate class
47
- * This is called automatically when chain.js is imported
48
- * @internal
49
- */
50
- export function __initPluginSystem(ChainedDateClass) {
51
- ChainedDateConstructor = ChainedDateClass;
32
+ return ChainedDate;
52
33
  }
53
34
  const registry = {};
35
+ const methodStates = {};
54
36
  /**
55
37
  * Extend ChainedDate with custom methods
56
38
  *
@@ -80,23 +62,23 @@ export function extend(pluginName, methods) {
80
62
  if (registry[pluginName]) {
81
63
  throw new Error(`Plugin "${pluginName}" is already registered. Use a different name or uninstall first.`);
82
64
  }
83
- // Get ChainedDate class and save original methods before overwriting
84
65
  const ChainedDateClass = getChainedDate();
85
- const originalMethods = new Map();
86
66
  Object.entries(methods).forEach(([methodName, fn]) => {
87
- // Save original method if it exists
67
+ const current = ChainedDateClass.prototype[methodName];
68
+ if (!methodStates[methodName]) {
69
+ methodStates[methodName] = {
70
+ original: typeof current === 'function' ? current : undefined,
71
+ owners: []
72
+ };
73
+ }
88
74
  if (methodName in ChainedDateClass.prototype) {
89
- const original = ChainedDateClass.prototype[methodName];
90
- if (typeof original === 'function') {
91
- originalMethods.set(methodName, original);
92
- }
93
75
  console.warn(`Method "${methodName}" already exists on ChainedDate and will be overwritten`);
94
76
  }
77
+ methodStates[methodName].owners.push(pluginName);
95
78
  // Add the plugin method
96
79
  ChainedDateClass.prototype[methodName] = fn;
97
80
  });
98
- // Register the plugin with its original methods
99
- registry[pluginName] = { plugin: methods, originalMethods };
81
+ registry[pluginName] = { plugin: methods };
100
82
  }
101
83
  /**
102
84
  * Remove a plugin and its methods from ChainedDate
@@ -113,20 +95,32 @@ export function uninstall(pluginName) {
113
95
  if (!entry) {
114
96
  throw new Error(`Plugin "${pluginName}" is not registered`);
115
97
  }
116
- // Get ChainedDate class and restore/remove methods
117
98
  const ChainedDateClass = getChainedDate();
118
99
  Object.keys(entry.plugin).forEach((methodName) => {
119
- // If there was an original method, restore it
120
- const original = entry.originalMethods.get(methodName);
121
- if (original) {
122
- ChainedDateClass.prototype[methodName] = original;
100
+ const state = methodStates[methodName];
101
+ if (!state) {
102
+ delete ChainedDateClass.prototype[methodName];
103
+ return;
104
+ }
105
+ state.owners = state.owners.filter((owner) => owner !== pluginName);
106
+ const nextOwner = state.owners[state.owners.length - 1];
107
+ if (nextOwner) {
108
+ const nextPlugin = registry[nextOwner];
109
+ if (nextPlugin && methodName in nextPlugin.plugin) {
110
+ ChainedDateClass.prototype[methodName] = nextPlugin.plugin[methodName];
111
+ return;
112
+ }
113
+ delete ChainedDateClass.prototype[methodName];
114
+ return;
115
+ }
116
+ if (state.original) {
117
+ ChainedDateClass.prototype[methodName] = state.original;
123
118
  }
124
119
  else {
125
- // Otherwise, delete the method entirely
126
120
  delete ChainedDateClass.prototype[methodName];
127
121
  }
122
+ delete methodStates[methodName];
128
123
  });
129
- // Remove from registry
130
124
  delete registry[pluginName];
131
125
  }
132
126
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"recurrence.d.ts","sourceRoot":"","sources":["../../src/recurrence.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AAGjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc;;oCAKjB,SAAS;mCACV,SAAS,OAAO,SAAS,UAAU,MAAM;6BAE/C,SAAS;;EAqBrC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAyC1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,KAAK,SAAO,GACX,IAAI,EAAE,CA6BR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAW/E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAgC5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CA6C/D"}
1
+ {"version":3,"file":"recurrence.d.ts","sourceRoot":"","sources":["../../src/recurrence.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AAGjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc;;oCAKjB,SAAS;mCACV,SAAS,OAAO,SAAS,UAAU,MAAM;6BAE/C,SAAS;;EAmBrC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAyC1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,KAAK,SAAO,GACX,IAAI,EAAE,CA6BR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAW/E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAgC5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CA6C/D"}
@@ -43,19 +43,17 @@ export function createRecurrence(rule) {
43
43
  isRecurrenceDate: (date) => isRecurrenceDate(date, rule),
44
44
  getAllOccurrences: (limit = 100) => {
45
45
  const occurrences = [];
46
- let current = new Date(startDate);
47
- let count = 0;
48
- while (count < limit) {
46
+ let current = new Date(startDate.getTime() - 1);
47
+ while (occurrences.length < limit) {
49
48
  if (rule.until && current > new Date(rule.until))
50
49
  break;
51
- if (rule.count && count >= rule.count)
50
+ if (rule.count && occurrences.length >= rule.count)
52
51
  break;
53
52
  const next = getNextOccurrence(rule, current);
54
53
  if (!next)
55
54
  break;
56
55
  occurrences.push(next);
57
56
  current = new Date(next.getTime() + 1);
58
- count++;
59
57
  }
60
58
  return occurrences;
61
59
  }
@@ -33,6 +33,8 @@ export declare function compareZoneOffsets(zoneA: string, zoneB: string, date?:
33
33
  export declare function reinterpretAsZone(date: Date, targetZone: string): Date | null;
34
34
  /**
35
35
  * Check if a date is in Daylight Saving Time for a given timezone
36
+ * Uses a yearly-offset heuristic: sample the zone's local year and treat the
37
+ * maximum observed UTC offset as the DST offset for that year.
36
38
  * @param date - date to check
37
39
  * @param zone - IANA timezone string
38
40
  */
@@ -50,7 +52,10 @@ export declare function getNextDSTTransition(date: Date, zone: string): Date | n
50
52
  * @param workHoursStart - work hours start (0-24)
51
53
  * @param workHoursEnd - work hours end (0-24)
52
54
  * @param date - reference date (default: today)
53
- * @returns array of overlapping hour ranges in UTC, or null if no overlap
55
+ * @returns one contiguous UTC overlap window, specifically the longest
56
+ * contiguous overlap slice. A full-day overlap is returned as
57
+ * `{ startUTC: 0, endUTC: 24 }`, and wrapped overlaps are returned with
58
+ * `endUTC` normalized back into the 0-24 range and may be less than `startUTC`
54
59
  */
55
60
  export declare function findCommonWorkingHours(zones: string[], workHoursStart?: number, workHoursEnd?: number, date?: Date): {
56
61
  startUTC: number;
@@ -1 +1 @@
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;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CA0B9D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAiD1E;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EAAE,EACf,cAAc,GAAE,MAAU,EAC1B,YAAY,GAAE,MAAW,EACzB,IAAI,GAAE,IAAiB,GACtB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA6B7C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAY5F;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAa7F;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAI/G;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,OAAO,GAAG,IAAI,CAIpG"}
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;AA6B5C,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;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CA4B9D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAmC1E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EAAE,EACf,cAAc,GAAE,MAAU,EAC1B,YAAY,GAAE,MAAW,EACzB,IAAI,GAAE,IAAiB,GACtB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqE7C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAY5F;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAa7F;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAI/G;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,OAAO,GAAG,IAAI,CAIpG"}
@@ -1,6 +1,20 @@
1
1
  /**
2
2
  * Timezone utilities using Intl API with fallbacks
3
3
  */
4
+ const DAY_MS = 24 * 60 * 60 * 1000;
5
+ const DAY_HOURS = 24;
6
+ const YEAR_MONTHS = Array.from({ length: 12 }, (_, month) => month);
7
+ function normalizeHourValue(hour) {
8
+ return ((hour % DAY_HOURS) + DAY_HOURS) % DAY_HOURS;
9
+ }
10
+ function pushSweepInterval(events, start, end) {
11
+ const clampedStart = Math.max(0, start);
12
+ const clampedEnd = Math.min(DAY_HOURS * 2, end);
13
+ if (clampedStart >= clampedEnd)
14
+ return;
15
+ events.push({ time: clampedStart, delta: 1 });
16
+ events.push({ time: clampedEnd, delta: -1 });
17
+ }
4
18
  /** Get offset (minutes) for a zone at a given date */
5
19
  export function getTimezoneOffset(zone, date = new Date()) {
6
20
  try {
@@ -99,30 +113,35 @@ export function reinterpretAsZone(date, targetZone) {
99
113
  }
100
114
  /**
101
115
  * Check if a date is in Daylight Saving Time for a given timezone
116
+ * Uses a yearly-offset heuristic: sample the zone's local year and treat the
117
+ * maximum observed UTC offset as the DST offset for that year.
102
118
  * @param date - date to check
103
119
  * @param zone - IANA timezone string
104
120
  */
105
121
  export function isDST(date, zone) {
106
122
  if (!isValidTimeZone(zone))
107
123
  return null;
108
- // Compare offset in January vs July - the one with larger offset is DST
109
- const january = new Date(date.getFullYear(), 0, 1);
110
- const july = new Date(date.getFullYear(), 6, 1);
111
- const janOffset = getTimezoneOffset(zone, january);
112
- const julOffset = getTimezoneOffset(zone, july);
124
+ const zonedDate = convertDateToZone(date, zone);
125
+ if (!zonedDate) {
126
+ return null;
127
+ }
113
128
  const currentOffset = getTimezoneOffset(zone, date);
114
- if (janOffset === null || julOffset === null || currentOffset === null) {
129
+ if (currentOffset === null) {
115
130
  return null;
116
131
  }
117
- // If offsets are the same, no DST in this zone
118
- if (janOffset === julOffset) {
132
+ const yearlyOffsets = new Set();
133
+ for (const month of YEAR_MONTHS) {
134
+ const sample = new Date(Date.UTC(zonedDate.year, month, 1, 12, 0, 0));
135
+ const offset = getTimezoneOffset(zone, sample);
136
+ if (offset === null) {
137
+ return null;
138
+ }
139
+ yearlyOffsets.add(offset);
140
+ }
141
+ if (yearlyOffsets.size <= 1) {
119
142
  return false;
120
143
  }
121
- // In northern hemisphere, summer (July) has larger offset
122
- // In southern hemisphere, summer (January) has larger offset
123
- // DST is whichever is the "larger" offset
124
- const maxOffset = Math.max(janOffset, julOffset);
125
- return currentOffset === maxOffset;
144
+ return currentOffset === Math.max(...yearlyOffsets);
126
145
  }
127
146
  /**
128
147
  * Get the next DST transition (if any) for a timezone
@@ -133,46 +152,35 @@ export function isDST(date, zone) {
133
152
  export function getNextDSTTransition(date, zone) {
134
153
  if (!isValidTimeZone(zone))
135
154
  return null;
136
- const january = new Date(date.getFullYear(), 0, 1);
137
- const july = new Date(date.getFullYear(), 6, 1);
138
- const janOffset = getTimezoneOffset(zone, january);
139
- const julOffset = getTimezoneOffset(zone, july);
140
- if (janOffset === null || julOffset === null)
141
- return null;
142
- // No DST if offsets are the same
143
- if (janOffset === julOffset)
144
- return null;
145
- // Binary search for the transition within the next year
146
155
  const currentOffset = getTimezoneOffset(zone, date);
147
156
  if (currentOffset === null)
148
157
  return null;
149
- // Check day by day for up to 366 days
150
- const searchDate = new Date(date);
151
- for (let i = 1; i <= 366; i++) {
152
- searchDate.setDate(searchDate.getDate() + 1);
153
- const newOffset = getTimezoneOffset(zone, searchDate);
154
- if (newOffset !== null && newOffset !== currentOffset) {
155
- // Found a transition, now narrow it down
156
- const prevDay = new Date(searchDate);
157
- prevDay.setDate(prevDay.getDate() - 1);
158
- // Binary search within the day
159
- let low = prevDay.getTime();
160
- let high = searchDate.getTime();
161
- while (high - low > 60000) { // 1 minute precision
162
- const mid = Math.floor((low + high) / 2);
163
- const midDate = new Date(mid);
164
- const midOffset = getTimezoneOffset(zone, midDate);
165
- if (midOffset === currentOffset) {
166
- low = mid;
167
- }
168
- else {
169
- high = mid;
170
- }
171
- }
172
- return new Date(high);
158
+ const startTime = date.getTime() + 1;
159
+ const searchLimit = startTime + 366 * DAY_MS;
160
+ let low = startTime;
161
+ let high = null;
162
+ for (let probeTime = startTime + DAY_MS; probeTime <= searchLimit; probeTime += DAY_MS) {
163
+ const probeOffset = getTimezoneOffset(zone, new Date(probeTime));
164
+ if (probeOffset !== null && probeOffset !== currentOffset) {
165
+ low = probeTime - DAY_MS;
166
+ high = probeTime;
167
+ break;
173
168
  }
174
169
  }
175
- return null;
170
+ if (high === null) {
171
+ return null;
172
+ }
173
+ while (high - low > 1) {
174
+ const mid = Math.floor((low + high) / 2);
175
+ const midOffset = getTimezoneOffset(zone, new Date(mid));
176
+ if (midOffset === currentOffset) {
177
+ low = mid;
178
+ }
179
+ else {
180
+ high = mid;
181
+ }
182
+ }
183
+ return new Date(high);
176
184
  }
177
185
  /**
178
186
  * Find overlapping working hours between multiple timezones
@@ -180,32 +188,64 @@ export function getNextDSTTransition(date, zone) {
180
188
  * @param workHoursStart - work hours start (0-24)
181
189
  * @param workHoursEnd - work hours end (0-24)
182
190
  * @param date - reference date (default: today)
183
- * @returns array of overlapping hour ranges in UTC, or null if no overlap
191
+ * @returns one contiguous UTC overlap window, specifically the longest
192
+ * contiguous overlap slice. A full-day overlap is returned as
193
+ * `{ startUTC: 0, endUTC: 24 }`, and wrapped overlaps are returned with
194
+ * `endUTC` normalized back into the 0-24 range and may be less than `startUTC`
184
195
  */
185
196
  export function findCommonWorkingHours(zones, workHoursStart = 9, workHoursEnd = 17, date = new Date()) {
186
197
  if (zones.length === 0)
187
198
  return null;
188
- // Convert each zone's work hours to UTC
189
- const utcRanges = zones.map(zone => {
199
+ const endHour = workHoursEnd < workHoursStart ? workHoursEnd + DAY_HOURS : workHoursEnd;
200
+ const duration = endHour - workHoursStart;
201
+ if (duration <= 0) {
202
+ return null;
203
+ }
204
+ const sweepEvents = [];
205
+ for (const zone of zones) {
190
206
  const offset = getTimezoneOffset(zone, date);
191
- if (offset === null)
207
+ if (offset === null) {
192
208
  return null;
193
- // Offset is in minutes, positive means ahead of UTC
194
- // So to convert local time to UTC, we subtract the offset
195
- const startUTC = workHoursStart - (offset / 60);
196
- const endUTC = workHoursEnd - (offset / 60);
197
- return { startUTC, endUTC };
198
- });
199
- if (utcRanges.some(r => r === null))
209
+ }
210
+ if (duration >= DAY_HOURS) {
211
+ pushSweepInterval(sweepEvents, 0, DAY_HOURS * 2);
212
+ continue;
213
+ }
214
+ const startUTC = normalizeHourValue(workHoursStart - (offset / 60));
215
+ pushSweepInterval(sweepEvents, startUTC, startUTC + duration);
216
+ pushSweepInterval(sweepEvents, startUTC + DAY_HOURS, startUTC + DAY_HOURS + duration);
217
+ }
218
+ sweepEvents.sort((a, b) => a.time - b.time || b.delta - a.delta);
219
+ let activeWindows = 0;
220
+ let previousTime = 0;
221
+ let bestOverlap = null;
222
+ for (let i = 0; i < sweepEvents.length;) {
223
+ const currentTime = sweepEvents[i].time;
224
+ if (currentTime > previousTime && activeWindows === zones.length) {
225
+ const candidate = { start: previousTime, end: currentTime };
226
+ if (bestOverlap === null ||
227
+ candidate.end - candidate.start > bestOverlap.end - bestOverlap.start ||
228
+ (candidate.end - candidate.start === bestOverlap.end - bestOverlap.start &&
229
+ candidate.start < bestOverlap.start)) {
230
+ bestOverlap = candidate;
231
+ }
232
+ }
233
+ while (i < sweepEvents.length && sweepEvents[i].time === currentTime) {
234
+ activeWindows += sweepEvents[i].delta;
235
+ i++;
236
+ }
237
+ previousTime = currentTime;
238
+ }
239
+ if (bestOverlap === null) {
200
240
  return null;
201
- const validRanges = utcRanges;
202
- // Find intersection of all ranges
203
- let overlapStart = Math.max(...validRanges.map(r => r.startUTC));
204
- let overlapEnd = Math.min(...validRanges.map(r => r.endUTC));
205
- if (overlapStart >= overlapEnd) {
206
- return null; // No overlap
207
241
  }
208
- return { startUTC: overlapStart, endUTC: overlapEnd };
242
+ const overlapDuration = bestOverlap.end - bestOverlap.start;
243
+ if (overlapDuration >= DAY_HOURS) {
244
+ return { startUTC: 0, endUTC: DAY_HOURS };
245
+ }
246
+ const startUTC = normalizeHourValue(bestOverlap.start);
247
+ const endUTC = normalizeHourValue(bestOverlap.start + overlapDuration);
248
+ return { startUTC, endUTC };
209
249
  }
210
250
  /**
211
251
  * Get all timezone abbreviations for a zone on a given date
@@ -14,8 +14,6 @@ export interface ParseOptions {
14
14
  strict?: boolean;
15
15
  /** Timezone to use for parsing */
16
16
  timezone?: string;
17
- /** Default locale for parsing */
18
- locale?: string;
19
17
  }
20
18
  /** Options for formatting operations */
21
19
  export interface FormatOptions {
@@ -63,8 +61,6 @@ export interface WorkingHoursConfig {
63
61
  start: number;
64
62
  end: number;
65
63
  }[];
66
- /** Timezone for working hours calculation */
67
- timezone?: string;
68
64
  }
69
65
  /** Result of age calculation */
70
66
  export interface AgeResult {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,26 @@
1
+ "use strict";
1
2
  /**
2
3
  * @fileoverview Finance utilities for market-aware date calculations
3
4
  * Provides US market hours, trading days, settlement dates, and options expiration
4
5
  */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.US_MARKET_HOLIDAYS = exports.MARKET_HOURS = void 0;
8
+ exports.isMarketHoliday = isMarketHoliday;
9
+ exports.isTradingDay = isTradingDay;
10
+ exports.isMarketOpen = isMarketOpen;
11
+ exports.getMarketHours = getMarketHours;
12
+ exports.getMarketOpen = getMarketOpen;
13
+ exports.getMarketClose = getMarketClose;
14
+ exports.getNextMarketOpen = getNextMarketOpen;
15
+ exports.getNextMarketClose = getNextMarketClose;
16
+ exports.getSettlementDate = getSettlementDate;
17
+ exports.getTradeDateFromSettlement = getTradeDateFromSettlement;
18
+ exports.eachTradingDay = eachTradingDay;
19
+ exports.countTradingDays = countTradingDays;
20
+ exports.addTradingDays = addTradingDays;
21
+ exports.getOptionsExpiration = getOptionsExpiration;
5
22
  /** Market hours for US exchanges */
6
- export const MARKET_HOURS = {
23
+ exports.MARKET_HOURS = {
7
24
  NYSE: {
8
25
  open: { hour: 9, minute: 30 },
9
26
  close: { hour: 16, minute: 0 },
@@ -20,7 +37,7 @@ export const MARKET_HOURS = {
20
37
  }
21
38
  };
22
39
  /** US market holidays (NYSE/NASDAQ follow same schedule) */
23
- export const US_MARKET_HOLIDAYS = [
40
+ exports.US_MARKET_HOLIDAYS = [
24
41
  "New Year's Day",
25
42
  'Martin Luther King Jr. Day',
26
43
  "Presidents' Day",
@@ -147,7 +164,7 @@ function isSameDay(date1, date2) {
147
164
  * isMarketHoliday(new Date('2024-01-02')); // false
148
165
  * ```
149
166
  */
150
- export function isMarketHoliday(date, market = 'NYSE') {
167
+ function isMarketHoliday(date, market = 'NYSE') {
151
168
  const d = toDate(date);
152
169
  const year = d.getFullYear();
153
170
  const holidays = getUSMarketHolidays(year);
@@ -165,7 +182,7 @@ export function isMarketHoliday(date, market = 'NYSE') {
165
182
  * isTradingDay(new Date('2024-01-13')); // false (Saturday)
166
183
  * ```
167
184
  */
168
- export function isTradingDay(date, market = 'NYSE') {
185
+ function isTradingDay(date, market = 'NYSE') {
169
186
  const d = toDate(date);
170
187
  const day = d.getDay();
171
188
  // Weekend check
@@ -189,12 +206,12 @@ export function isTradingDay(date, market = 'NYSE') {
189
206
  * isMarketOpen(new Date('2024-01-15T10:30:00-05:00')); // true
190
207
  * ```
191
208
  */
192
- export function isMarketOpen(date, market = 'NYSE') {
209
+ function isMarketOpen(date, market = 'NYSE') {
193
210
  const d = toDate(date);
194
211
  // First check if it's a trading day
195
212
  if (!isTradingDay(d, market))
196
213
  return false;
197
- const hours = MARKET_HOURS[market];
214
+ const hours = exports.MARKET_HOURS[market];
198
215
  // Convert to market timezone for comparison
199
216
  // For simplicity, we assume the input is already in market timezone
200
217
  // or we compare hours directly
@@ -216,8 +233,8 @@ export function isMarketOpen(date, market = 'NYSE') {
216
233
  * console.log(hours.open); // { hour: 9, minute: 30 }
217
234
  * ```
218
235
  */
219
- export function getMarketHours(market = 'NYSE') {
220
- const source = MARKET_HOURS[market];
236
+ function getMarketHours(market = 'NYSE') {
237
+ const source = exports.MARKET_HOURS[market];
221
238
  return {
222
239
  open: { ...source.open },
223
240
  close: { ...source.close },
@@ -238,9 +255,9 @@ export function getMarketHours(market = 'NYSE') {
238
255
  * console.log(open); // 2024-01-15T09:30:00
239
256
  * ```
240
257
  */
241
- export function getMarketOpen(date, market = 'NYSE') {
258
+ function getMarketOpen(date, market = 'NYSE') {
242
259
  const d = toDate(date);
243
- const hours = MARKET_HOURS[market];
260
+ const hours = exports.MARKET_HOURS[market];
244
261
  const result = new Date(d);
245
262
  result.setHours(hours.open.hour, hours.open.minute, 0, 0);
246
263
  return result;
@@ -257,9 +274,9 @@ export function getMarketOpen(date, market = 'NYSE') {
257
274
  * console.log(close); // 2024-01-15T16:00:00
258
275
  * ```
259
276
  */
260
- export function getMarketClose(date, market = 'NYSE') {
277
+ function getMarketClose(date, market = 'NYSE') {
261
278
  const d = toDate(date);
262
- const hours = MARKET_HOURS[market];
279
+ const hours = exports.MARKET_HOURS[market];
263
280
  const result = new Date(d);
264
281
  result.setHours(hours.close.hour, hours.close.minute, 0, 0);
265
282
  return result;
@@ -276,9 +293,9 @@ export function getMarketClose(date, market = 'NYSE') {
276
293
  * const nextOpen = getNextMarketOpen(new Date('2024-01-12T17:00:00'));
277
294
  * ```
278
295
  */
279
- export function getNextMarketOpen(after, market = 'NYSE') {
296
+ function getNextMarketOpen(after, market = 'NYSE') {
280
297
  const d = toDate(after);
281
- const hours = MARKET_HOURS[market];
298
+ const hours = exports.MARKET_HOURS[market];
282
299
  // Start with current day's open
283
300
  let candidate = getMarketOpen(d, market);
284
301
  // If we're past today's open, start from tomorrow
@@ -305,9 +322,9 @@ export function getNextMarketOpen(after, market = 'NYSE') {
305
322
  * // Returns 2024-01-15T16:00:00 (same day close)
306
323
  * ```
307
324
  */
308
- export function getNextMarketClose(after, market = 'NYSE') {
325
+ function getNextMarketClose(after, market = 'NYSE') {
309
326
  const d = toDate(after);
310
- const hours = MARKET_HOURS[market];
327
+ const hours = exports.MARKET_HOURS[market];
311
328
  // Start with current day's close
312
329
  let candidate = getMarketClose(d, market);
313
330
  // If we're past today's close or not a trading day, go to next trading day
@@ -335,7 +352,7 @@ export function getNextMarketClose(after, market = 'NYSE') {
335
352
  * // Returns 2024-01-17 (skipping weekends/holidays)
336
353
  * ```
337
354
  */
338
- export function getSettlementDate(tradeDate, days, market = 'NYSE') {
355
+ function getSettlementDate(tradeDate, days, market = 'NYSE') {
339
356
  const d = toDate(tradeDate);
340
357
  const result = new Date(d);
341
358
  result.setHours(0, 0, 0, 0);
@@ -361,7 +378,7 @@ export function getSettlementDate(tradeDate, days, market = 'NYSE') {
361
378
  * // Returns 2024-01-15
362
379
  * ```
363
380
  */
364
- export function getTradeDateFromSettlement(settlementDate, days, market = 'NYSE') {
381
+ function getTradeDateFromSettlement(settlementDate, days, market = 'NYSE') {
365
382
  const d = toDate(settlementDate);
366
383
  const result = new Date(d);
367
384
  result.setHours(0, 0, 0, 0);
@@ -387,7 +404,7 @@ export function getTradeDateFromSettlement(settlementDate, days, market = 'NYSE'
387
404
  * // Returns Mon, Tue, Wed, Thu, Fri (if no holidays)
388
405
  * ```
389
406
  */
390
- export function eachTradingDay(start, end, market = 'NYSE') {
407
+ function eachTradingDay(start, end, market = 'NYSE') {
391
408
  const startDate = toDate(start);
392
409
  const endDate = toDate(end);
393
410
  startDate.setHours(0, 0, 0, 0);
@@ -415,7 +432,7 @@ export function eachTradingDay(start, end, market = 'NYSE') {
415
432
  * // Returns 5 (Mon-Fri if no holidays)
416
433
  * ```
417
434
  */
418
- export function countTradingDays(start, end, market = 'NYSE') {
435
+ function countTradingDays(start, end, market = 'NYSE') {
419
436
  return eachTradingDay(start, end, market).length;
420
437
  }
421
438
  /**
@@ -431,7 +448,7 @@ export function countTradingDays(start, end, market = 'NYSE') {
431
448
  * // Returns 5 trading days later
432
449
  * ```
433
450
  */
434
- export function addTradingDays(date, days, market = 'NYSE') {
451
+ function addTradingDays(date, days, market = 'NYSE') {
435
452
  const d = toDate(date);
436
453
  const result = new Date(d);
437
454
  result.setHours(0, 0, 0, 0);
@@ -466,7 +483,7 @@ export function addTradingDays(date, days, market = 'NYSE') {
466
483
  * const quarterly = getOptionsExpiration(2024, 3, 'quarterly');
467
484
  * ```
468
485
  */
469
- export function getOptionsExpiration(year, month, type = 'monthly') {
486
+ function getOptionsExpiration(year, month, type = 'monthly') {
470
487
  // Adjust month to 0-indexed
471
488
  const monthIndex = month - 1;
472
489
  switch (type) {