ts-time-utils 4.0.1 → 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 (81) hide show
  1. package/README.md +175 -30
  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/finance.d.ts +236 -0
  15. package/dist/esm/finance.d.ts.map +1 -0
  16. package/dist/esm/finance.js +495 -0
  17. package/dist/esm/healthcare.d.ts +260 -0
  18. package/dist/esm/healthcare.d.ts.map +1 -0
  19. package/dist/esm/healthcare.js +447 -0
  20. package/dist/esm/index.d.ts +6 -0
  21. package/dist/esm/index.d.ts.map +1 -1
  22. package/dist/esm/index.js +6 -0
  23. package/dist/esm/naturalLanguage.d.ts +1 -3
  24. package/dist/esm/naturalLanguage.d.ts.map +1 -1
  25. package/dist/esm/naturalLanguage.js +9 -2
  26. package/dist/esm/plugins.d.ts +0 -6
  27. package/dist/esm/plugins.d.ts.map +1 -1
  28. package/dist/esm/plugins.js +36 -42
  29. package/dist/esm/recurrence.d.ts.map +1 -1
  30. package/dist/esm/recurrence.js +3 -5
  31. package/dist/esm/scheduling.d.ts +206 -0
  32. package/dist/esm/scheduling.d.ts.map +1 -0
  33. package/dist/esm/scheduling.js +329 -0
  34. package/dist/esm/timezone.d.ts +6 -1
  35. package/dist/esm/timezone.d.ts.map +1 -1
  36. package/dist/esm/timezone.js +106 -66
  37. package/dist/esm/types.d.ts +0 -4
  38. package/dist/esm/types.d.ts.map +1 -1
  39. package/dist/finance.cjs +512 -0
  40. package/dist/finance.d.ts +236 -0
  41. package/dist/finance.d.ts.map +1 -0
  42. package/dist/{fiscal.js → fiscal.cjs} +36 -17
  43. package/dist/{format.js → format.cjs} +83 -70
  44. package/dist/healthcare.cjs +462 -0
  45. package/dist/healthcare.d.ts +260 -0
  46. package/dist/healthcare.d.ts.map +1 -0
  47. package/dist/{holidays.js → holidays.cjs} +52 -25
  48. package/dist/index.cjs +595 -0
  49. package/dist/index.d.ts +6 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/{interval.js → interval.cjs} +24 -11
  52. package/dist/{iterate.js → iterate.cjs} +84 -41
  53. package/dist/{locale.js → locale.cjs} +54 -26
  54. package/dist/{naturalLanguage.js → naturalLanguage.cjs} +36 -23
  55. package/dist/naturalLanguage.d.ts +1 -3
  56. package/dist/naturalLanguage.d.ts.map +1 -1
  57. package/dist/{parse.js → parse.cjs} +24 -11
  58. package/dist/{performance.js → performance.cjs} +23 -10
  59. package/dist/{plugins.js → plugins.cjs} +48 -47
  60. package/dist/plugins.d.ts +0 -6
  61. package/dist/plugins.d.ts.map +1 -1
  62. package/dist/{precision.js → precision.cjs} +74 -37
  63. package/dist/{rangePresets.js → rangePresets.cjs} +40 -19
  64. package/dist/{recurrence.js → recurrence.cjs} +27 -21
  65. package/dist/recurrence.d.ts.map +1 -1
  66. package/dist/scheduling.cjs +344 -0
  67. package/dist/scheduling.d.ts +206 -0
  68. package/dist/scheduling.d.ts.map +1 -0
  69. package/dist/{serialize.js → serialize.cjs} +36 -17
  70. package/dist/{temporal.js → temporal.cjs} +28 -13
  71. package/dist/{timezone.js → timezone.cjs} +140 -82
  72. package/dist/timezone.d.ts +6 -1
  73. package/dist/timezone.d.ts.map +1 -1
  74. package/dist/{types.js → types.cjs} +9 -3
  75. package/dist/types.d.ts +0 -4
  76. package/dist/types.d.ts.map +1 -1
  77. package/dist/{validate.js → validate.cjs} +54 -26
  78. package/dist/{workingHours.js → workingHours.cjs} +36 -17
  79. package/package.json +52 -34
  80. package/dist/constants.js +0 -16
  81. package/dist/index.js +0 -66
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * Plugin system for extending ChainedDate with custom methods
3
4
  *
@@ -19,38 +20,26 @@
19
20
  * chain(new Date()).nextMonday().format('YYYY-MM-DD');
20
21
  * ```
21
22
  */
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;
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.extend = extend;
25
+ exports.uninstall = uninstall;
26
+ exports.getRegisteredPlugins = getRegisteredPlugins;
27
+ exports.getPluginMethods = getPluginMethods;
28
+ exports.isPluginRegistered = isPluginRegistered;
29
+ const chain_js_1 = require("./chain.cjs");
25
30
  /**
26
- * Get ChainedDate class lazily to ensure it's fully initialized
31
+ * Get ChainedDate class for prototype mutation.
32
+ * Importing `plugins` now brings in `chain` directly, so the class is available
33
+ * without a hidden global handshake.
27
34
  */
28
35
  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
- }
36
+ if (!chain_js_1.ChainedDate) {
37
+ throw new Error('ChainedDate export is not available yet. Import chain.js before registering plugins.');
42
38
  }
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;
39
+ return chain_js_1.ChainedDate;
52
40
  }
53
41
  const registry = {};
42
+ const methodStates = {};
54
43
  /**
55
44
  * Extend ChainedDate with custom methods
56
45
  *
@@ -76,27 +65,27 @@ const registry = {};
76
65
  * chain(new Date()).addBusinessDays(5);
77
66
  * ```
78
67
  */
79
- export function extend(pluginName, methods) {
68
+ function extend(pluginName, methods) {
80
69
  if (registry[pluginName]) {
81
70
  throw new Error(`Plugin "${pluginName}" is already registered. Use a different name or uninstall first.`);
82
71
  }
83
- // Get ChainedDate class and save original methods before overwriting
84
72
  const ChainedDateClass = getChainedDate();
85
- const originalMethods = new Map();
86
73
  Object.entries(methods).forEach(([methodName, fn]) => {
87
- // Save original method if it exists
74
+ const current = ChainedDateClass.prototype[methodName];
75
+ if (!methodStates[methodName]) {
76
+ methodStates[methodName] = {
77
+ original: typeof current === 'function' ? current : undefined,
78
+ owners: []
79
+ };
80
+ }
88
81
  if (methodName in ChainedDateClass.prototype) {
89
- const original = ChainedDateClass.prototype[methodName];
90
- if (typeof original === 'function') {
91
- originalMethods.set(methodName, original);
92
- }
93
82
  console.warn(`Method "${methodName}" already exists on ChainedDate and will be overwritten`);
94
83
  }
84
+ methodStates[methodName].owners.push(pluginName);
95
85
  // Add the plugin method
96
86
  ChainedDateClass.prototype[methodName] = fn;
97
87
  });
98
- // Register the plugin with its original methods
99
- registry[pluginName] = { plugin: methods, originalMethods };
88
+ registry[pluginName] = { plugin: methods };
100
89
  }
101
90
  /**
102
91
  * Remove a plugin and its methods from ChainedDate
@@ -108,25 +97,37 @@ export function extend(pluginName, methods) {
108
97
  * uninstall('businessDays');
109
98
  * ```
110
99
  */
111
- export function uninstall(pluginName) {
100
+ function uninstall(pluginName) {
112
101
  const entry = registry[pluginName];
113
102
  if (!entry) {
114
103
  throw new Error(`Plugin "${pluginName}" is not registered`);
115
104
  }
116
- // Get ChainedDate class and restore/remove methods
117
105
  const ChainedDateClass = getChainedDate();
118
106
  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;
107
+ const state = methodStates[methodName];
108
+ if (!state) {
109
+ delete ChainedDateClass.prototype[methodName];
110
+ return;
111
+ }
112
+ state.owners = state.owners.filter((owner) => owner !== pluginName);
113
+ const nextOwner = state.owners[state.owners.length - 1];
114
+ if (nextOwner) {
115
+ const nextPlugin = registry[nextOwner];
116
+ if (nextPlugin && methodName in nextPlugin.plugin) {
117
+ ChainedDateClass.prototype[methodName] = nextPlugin.plugin[methodName];
118
+ return;
119
+ }
120
+ delete ChainedDateClass.prototype[methodName];
121
+ return;
122
+ }
123
+ if (state.original) {
124
+ ChainedDateClass.prototype[methodName] = state.original;
123
125
  }
124
126
  else {
125
- // Otherwise, delete the method entirely
126
127
  delete ChainedDateClass.prototype[methodName];
127
128
  }
129
+ delete methodStates[methodName];
128
130
  });
129
- // Remove from registry
130
131
  delete registry[pluginName];
131
132
  }
132
133
  /**
@@ -139,7 +140,7 @@ export function uninstall(pluginName) {
139
140
  * getRegisteredPlugins(); // ['businessDays', 'myPlugin']
140
141
  * ```
141
142
  */
142
- export function getRegisteredPlugins() {
143
+ function getRegisteredPlugins() {
143
144
  return Object.keys(registry);
144
145
  }
145
146
  /**
@@ -153,7 +154,7 @@ export function getRegisteredPlugins() {
153
154
  * getPluginMethods('businessDays'); // ['addBusinessDays', 'subtractBusinessDays']
154
155
  * ```
155
156
  */
156
- export function getPluginMethods(pluginName) {
157
+ function getPluginMethods(pluginName) {
157
158
  const entry = registry[pluginName];
158
159
  return entry ? Object.keys(entry.plugin) : [];
159
160
  }
@@ -168,6 +169,6 @@ export function getPluginMethods(pluginName) {
168
169
  * isPluginRegistered('businessDays'); // true
169
170
  * ```
170
171
  */
171
- export function isPluginRegistered(pluginName) {
172
+ function isPluginRegistered(pluginName) {
172
173
  return pluginName in registry;
173
174
  }
package/dist/plugins.d.ts CHANGED
@@ -19,12 +19,6 @@
19
19
  * chain(new Date()).nextMonday().format('YYYY-MM-DD');
20
20
  * ```
21
21
  */
22
- /**
23
- * Initialize the plugin system with ChainedDate class
24
- * This is called automatically when chain.js is imported
25
- * @internal
26
- */
27
- export declare function __initPluginSystem(ChainedDateClass: any): void;
28
22
  /**
29
23
  * Plugin function type - methods receive ChainedDate instance as `this`
30
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA0BH;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,QAEvD;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAAC;CACtC;AAcD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAwBhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAqBlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,iBAAiB;CAAG"}
1
+ {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAgBH;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAAC;CACtC;AAoBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAwBhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAqClD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,iBAAiB;CAAG"}
@@ -1,11 +1,47 @@
1
+ "use strict";
1
2
  /**
2
3
  * @fileoverview High-precision time utilities
3
4
  * Handles nanoseconds, BigInt timestamps, sub-millisecond operations
4
5
  */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.LEAP_SECONDS = exports.ValidDate = void 0;
8
+ exports.createNanosecondTimestamp = createNanosecondTimestamp;
9
+ exports.fromNanoseconds = fromNanoseconds;
10
+ exports.dateToNanoseconds = dateToNanoseconds;
11
+ exports.nanosecondsToDate = nanosecondsToDate;
12
+ exports.addNanoseconds = addNanoseconds;
13
+ exports.subtractNanoseconds = subtractNanoseconds;
14
+ exports.compareNanoseconds = compareNanoseconds;
15
+ exports.nowNanoseconds = nowNanoseconds;
16
+ exports.formatNanoseconds = formatNanoseconds;
17
+ exports.parseNanoseconds = parseNanoseconds;
18
+ exports.createHighResDuration = createHighResDuration;
19
+ exports.addHighResDuration = addHighResDuration;
20
+ exports.subtractHighResDuration = subtractHighResDuration;
21
+ exports.highResDurationToMs = highResDurationToMs;
22
+ exports.msToHighResDuration = msToHighResDuration;
23
+ exports.toBigIntMs = toBigIntMs;
24
+ exports.fromBigIntMs = fromBigIntMs;
25
+ exports.toBigIntSeconds = toBigIntSeconds;
26
+ exports.fromBigIntSeconds = fromBigIntSeconds;
27
+ exports.addBigIntMs = addBigIntMs;
28
+ exports.subtractBigIntMs = subtractBigIntMs;
29
+ exports.diffBigIntMs = diffBigIntMs;
30
+ exports.isInDSTGap = isInDSTGap;
31
+ exports.isInDSTOverlap = isInDSTOverlap;
32
+ exports.getDSTTransitionsInYear = getDSTTransitionsInYear;
33
+ exports.resolveAmbiguousTime = resolveAmbiguousTime;
34
+ exports.ensureValidDate = ensureValidDate;
35
+ exports.parseValidDate = parseValidDate;
36
+ exports.assertValidDate = assertValidDate;
37
+ exports.leapSecondsBetween = leapSecondsBetween;
38
+ exports.isNearLeapSecond = isNearLeapSecond;
39
+ exports.taiToUtc = taiToUtc;
40
+ exports.utcToTai = utcToTai;
5
41
  /**
6
42
  * Create a nanosecond timestamp from components
7
43
  */
8
- export function createNanosecondTimestamp(milliseconds, nanoseconds = 0) {
44
+ function createNanosecondTimestamp(milliseconds, nanoseconds = 0) {
9
45
  // Normalize: ensure nanoseconds is 0-999999
10
46
  const extraMs = Math.floor(nanoseconds / 1000000);
11
47
  const normalizedNs = nanoseconds % 1000000;
@@ -20,7 +56,7 @@ export function createNanosecondTimestamp(milliseconds, nanoseconds = 0) {
20
56
  /**
21
57
  * Create a nanosecond timestamp from BigInt
22
58
  */
23
- export function fromNanoseconds(totalNs) {
59
+ function fromNanoseconds(totalNs) {
24
60
  const ms = Number(totalNs / BigInt(1000000));
25
61
  const ns = Number(totalNs % BigInt(1000000));
26
62
  return {
@@ -32,32 +68,32 @@ export function fromNanoseconds(totalNs) {
32
68
  /**
33
69
  * Create a nanosecond timestamp from a Date
34
70
  */
35
- export function dateToNanoseconds(date) {
71
+ function dateToNanoseconds(date) {
36
72
  return createNanosecondTimestamp(date.getTime(), 0);
37
73
  }
38
74
  /**
39
75
  * Convert nanosecond timestamp to Date (loses sub-millisecond precision)
40
76
  */
41
- export function nanosecondsToDate(timestamp) {
77
+ function nanosecondsToDate(timestamp) {
42
78
  return new Date(timestamp.milliseconds);
43
79
  }
44
80
  /**
45
81
  * Add two nanosecond timestamps
46
82
  */
47
- export function addNanoseconds(a, b) {
83
+ function addNanoseconds(a, b) {
48
84
  return fromNanoseconds(a.totalNanoseconds + b.totalNanoseconds);
49
85
  }
50
86
  /**
51
87
  * Subtract nanosecond timestamps
52
88
  */
53
- export function subtractNanoseconds(a, b) {
89
+ function subtractNanoseconds(a, b) {
54
90
  return fromNanoseconds(a.totalNanoseconds - b.totalNanoseconds);
55
91
  }
56
92
  /**
57
93
  * Compare nanosecond timestamps
58
94
  * @returns -1 if a < b, 0 if equal, 1 if a > b
59
95
  */
60
- export function compareNanoseconds(a, b) {
96
+ function compareNanoseconds(a, b) {
61
97
  if (a.totalNanoseconds < b.totalNanoseconds)
62
98
  return -1;
63
99
  if (a.totalNanoseconds > b.totalNanoseconds)
@@ -68,7 +104,7 @@ export function compareNanoseconds(a, b) {
68
104
  * Get current time with nanosecond precision (if available)
69
105
  * Falls back to millisecond precision if performance.now() not available
70
106
  */
71
- export function nowNanoseconds() {
107
+ function nowNanoseconds() {
72
108
  const now = Date.now();
73
109
  // Try to get sub-millisecond precision from performance.now()
74
110
  if (typeof performance !== 'undefined' && performance.now) {
@@ -81,7 +117,7 @@ export function nowNanoseconds() {
81
117
  /**
82
118
  * Format nanosecond timestamp to ISO string with sub-millisecond precision
83
119
  */
84
- export function formatNanoseconds(timestamp) {
120
+ function formatNanoseconds(timestamp) {
85
121
  const date = nanosecondsToDate(timestamp);
86
122
  const isoBase = date.toISOString().slice(0, -1); // Remove trailing 'Z'
87
123
  // Add nanoseconds (6 additional digits after milliseconds)
@@ -91,7 +127,7 @@ export function formatNanoseconds(timestamp) {
91
127
  /**
92
128
  * Parse ISO string with nanosecond precision
93
129
  */
94
- export function parseNanoseconds(isoString) {
130
+ function parseNanoseconds(isoString) {
95
131
  // Match ISO format: 2024-03-25T14:30:45.123456789Z
96
132
  const match = isoString.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3,9})Z?$/);
97
133
  if (!match) {
@@ -114,7 +150,7 @@ export function parseNanoseconds(isoString) {
114
150
  /**
115
151
  * Create a high-resolution duration
116
152
  */
117
- export function createHighResDuration(seconds, nanoseconds = 0) {
153
+ function createHighResDuration(seconds, nanoseconds = 0) {
118
154
  // Normalize: carry over extra seconds from nanoseconds
119
155
  const extraSeconds = Math.floor(nanoseconds / 1000000000);
120
156
  const normalizedNs = nanoseconds % 1000000000;
@@ -126,7 +162,7 @@ export function createHighResDuration(seconds, nanoseconds = 0) {
126
162
  /**
127
163
  * Add two high-resolution durations
128
164
  */
129
- export function addHighResDuration(a, b) {
165
+ function addHighResDuration(a, b) {
130
166
  const totalNs = a.nanoseconds + b.nanoseconds;
131
167
  const extraSeconds = Math.floor(totalNs / 1000000000);
132
168
  const ns = totalNs % 1000000000;
@@ -138,7 +174,7 @@ export function addHighResDuration(a, b) {
138
174
  /**
139
175
  * Subtract high-resolution durations
140
176
  */
141
- export function subtractHighResDuration(a, b) {
177
+ function subtractHighResDuration(a, b) {
142
178
  let totalNs = a.nanoseconds - b.nanoseconds;
143
179
  let seconds = a.seconds - b.seconds;
144
180
  if (totalNs < 0) {
@@ -150,13 +186,13 @@ export function subtractHighResDuration(a, b) {
150
186
  /**
151
187
  * Convert high-resolution duration to milliseconds
152
188
  */
153
- export function highResDurationToMs(duration) {
189
+ function highResDurationToMs(duration) {
154
190
  return duration.seconds * 1000 + duration.nanoseconds / 1000000;
155
191
  }
156
192
  /**
157
193
  * Convert milliseconds to high-resolution duration
158
194
  */
159
- export function msToHighResDuration(ms) {
195
+ function msToHighResDuration(ms) {
160
196
  const seconds = Math.floor(ms / 1000);
161
197
  const nanoseconds = Math.round((ms % 1000) * 1000000);
162
198
  return { seconds, nanoseconds };
@@ -165,45 +201,45 @@ export function msToHighResDuration(ms) {
165
201
  /**
166
202
  * Convert Unix epoch milliseconds to BigInt
167
203
  */
168
- export function toBigIntMs(date) {
204
+ function toBigIntMs(date) {
169
205
  return BigInt(date.getTime());
170
206
  }
171
207
  /**
172
208
  * Convert BigInt milliseconds to Date
173
209
  */
174
- export function fromBigIntMs(ms) {
210
+ function fromBigIntMs(ms) {
175
211
  return new Date(Number(ms));
176
212
  }
177
213
  /**
178
214
  * Convert Unix epoch seconds to BigInt
179
215
  */
180
- export function toBigIntSeconds(date) {
216
+ function toBigIntSeconds(date) {
181
217
  return BigInt(Math.floor(date.getTime() / 1000));
182
218
  }
183
219
  /**
184
220
  * Convert BigInt seconds to Date
185
221
  */
186
- export function fromBigIntSeconds(seconds) {
222
+ function fromBigIntSeconds(seconds) {
187
223
  return new Date(Number(seconds) * 1000);
188
224
  }
189
225
  /**
190
226
  * Add milliseconds (as BigInt) to a date
191
227
  */
192
- export function addBigIntMs(date, ms) {
228
+ function addBigIntMs(date, ms) {
193
229
  const current = toBigIntMs(date);
194
230
  return fromBigIntMs(current + ms);
195
231
  }
196
232
  /**
197
233
  * Subtract milliseconds (as BigInt) from a date
198
234
  */
199
- export function subtractBigIntMs(date, ms) {
235
+ function subtractBigIntMs(date, ms) {
200
236
  const current = toBigIntMs(date);
201
237
  return fromBigIntMs(current - ms);
202
238
  }
203
239
  /**
204
240
  * Calculate difference between dates in BigInt milliseconds
205
241
  */
206
- export function diffBigIntMs(a, b) {
242
+ function diffBigIntMs(a, b) {
207
243
  return toBigIntMs(a) - toBigIntMs(b);
208
244
  }
209
245
  /**
@@ -211,7 +247,7 @@ export function diffBigIntMs(a, b) {
211
247
  * @param date - Date to check
212
248
  * @param timeZone - IANA timezone (optional, uses local if not provided)
213
249
  */
214
- export function isInDSTGap(date, timeZone) {
250
+ function isInDSTGap(date, timeZone) {
215
251
  if (timeZone) {
216
252
  // For specific timezone, we need to check around this time
217
253
  const formatter = new Intl.DateTimeFormat('en-US', {
@@ -255,7 +291,7 @@ export function isInDSTGap(date, timeZone) {
255
291
  * @param date - Date to check
256
292
  * @param timeZone - IANA timezone (optional, uses local if not provided)
257
293
  */
258
- export function isInDSTOverlap(date, timeZone) {
294
+ function isInDSTOverlap(date, timeZone) {
259
295
  if (timeZone) {
260
296
  // Similar approach as isInDSTGap but for fall-back
261
297
  // This is harder to detect accurately without full TZ database
@@ -272,7 +308,7 @@ export function isInDSTOverlap(date, timeZone) {
272
308
  /**
273
309
  * Find DST transitions in a year for local timezone
274
310
  */
275
- export function getDSTTransitionsInYear(year) {
311
+ function getDSTTransitionsInYear(year) {
276
312
  const transitions = [];
277
313
  let prevOffset = new Date(year, 0, 1).getTimezoneOffset();
278
314
  // Check each day of the year
@@ -312,7 +348,7 @@ export function getDSTTransitionsInYear(year) {
312
348
  * @param date - Potentially ambiguous date
313
349
  * @param prefer - Prefer 'earlier' or 'later' interpretation
314
350
  */
315
- export function resolveAmbiguousTime(date, prefer = 'earlier') {
351
+ function resolveAmbiguousTime(date, prefer = 'earlier') {
316
352
  if (!isInDSTOverlap(date)) {
317
353
  return date;
318
354
  }
@@ -333,7 +369,7 @@ export function resolveAmbiguousTime(date, prefer = 'earlier') {
333
369
  /**
334
370
  * Validated Date wrapper that guarantees a valid date
335
371
  */
336
- export class ValidDate {
372
+ class ValidDate {
337
373
  constructor(date) {
338
374
  this._date = date;
339
375
  }
@@ -394,16 +430,17 @@ export class ValidDate {
394
430
  return this._date.toLocaleString(locale, options);
395
431
  }
396
432
  }
433
+ exports.ValidDate = ValidDate;
397
434
  /**
398
435
  * Ensure a date is valid, with fallback
399
436
  */
400
- export function ensureValidDate(date, fallback = new Date()) {
437
+ function ensureValidDate(date, fallback = new Date()) {
401
438
  return isNaN(date.getTime()) ? fallback : date;
402
439
  }
403
440
  /**
404
441
  * Parse date with validation
405
442
  */
406
- export function parseValidDate(input) {
443
+ function parseValidDate(input) {
407
444
  if (input instanceof Date) {
408
445
  return isNaN(input.getTime()) ? null : input;
409
446
  }
@@ -413,7 +450,7 @@ export function parseValidDate(input) {
413
450
  /**
414
451
  * Assert date is valid, throws if not
415
452
  */
416
- export function assertValidDate(date, message) {
453
+ function assertValidDate(date, message) {
417
454
  if (isNaN(date.getTime())) {
418
455
  throw new Error(message || 'Invalid Date');
419
456
  }
@@ -423,7 +460,7 @@ export function assertValidDate(date, message) {
423
460
  * Known leap seconds (added at end of these dates, 23:59:60 UTC)
424
461
  * List from https://www.ietf.org/timezones/data/leap-seconds.list
425
462
  */
426
- export const LEAP_SECONDS = [
463
+ exports.LEAP_SECONDS = [
427
464
  new Date('1972-06-30T23:59:59Z'),
428
465
  new Date('1972-12-31T23:59:59Z'),
429
466
  new Date('1973-12-31T23:59:59Z'),
@@ -455,9 +492,9 @@ export const LEAP_SECONDS = [
455
492
  /**
456
493
  * Get number of leap seconds between two dates
457
494
  */
458
- export function leapSecondsBetween(start, end) {
495
+ function leapSecondsBetween(start, end) {
459
496
  let count = 0;
460
- for (const ls of LEAP_SECONDS) {
497
+ for (const ls of exports.LEAP_SECONDS) {
461
498
  if (ls >= start && ls < end) {
462
499
  count++;
463
500
  }
@@ -467,15 +504,15 @@ export function leapSecondsBetween(start, end) {
467
504
  /**
468
505
  * Check if a date is near a leap second (within 1 second)
469
506
  */
470
- export function isNearLeapSecond(date) {
507
+ function isNearLeapSecond(date) {
471
508
  const time = date.getTime();
472
- return LEAP_SECONDS.some(ls => Math.abs(ls.getTime() - time) <= 1000);
509
+ return exports.LEAP_SECONDS.some(ls => Math.abs(ls.getTime() - time) <= 1000);
473
510
  }
474
511
  /**
475
512
  * Convert TAI (International Atomic Time) to UTC
476
513
  * TAI = UTC + accumulated leap seconds + 10 (initial offset)
477
514
  */
478
- export function taiToUtc(taiMs) {
515
+ function taiToUtc(taiMs) {
479
516
  // Count leap seconds before this TAI time
480
517
  const utcApprox = new Date(taiMs);
481
518
  const leapSeconds = leapSecondsBetween(new Date(0), utcApprox);
@@ -485,7 +522,7 @@ export function taiToUtc(taiMs) {
485
522
  /**
486
523
  * Convert UTC to TAI
487
524
  */
488
- export function utcToTai(date) {
525
+ function utcToTai(date) {
489
526
  const leapSeconds = leapSecondsBetween(new Date(0), date);
490
527
  return date.getTime() + (leapSeconds + 10) * 1000;
491
528
  }
@@ -1,6 +1,27 @@
1
+ "use strict";
1
2
  /**
2
3
  * Predefined date range helpers for common time periods
3
4
  */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RANGE_PRESETS = void 0;
7
+ exports.today = today;
8
+ exports.yesterday = yesterday;
9
+ exports.tomorrow = tomorrow;
10
+ exports.lastNDays = lastNDays;
11
+ exports.nextNDays = nextNDays;
12
+ exports.thisWeek = thisWeek;
13
+ exports.lastWeek = lastWeek;
14
+ exports.nextWeek = nextWeek;
15
+ exports.thisMonth = thisMonth;
16
+ exports.lastMonth = lastMonth;
17
+ exports.nextMonth = nextMonth;
18
+ exports.thisYear = thisYear;
19
+ exports.lastYear = lastYear;
20
+ exports.nextYear = nextYear;
21
+ exports.rollingWindowDays = rollingWindowDays;
22
+ exports.quarterRange = quarterRange;
23
+ exports.lastQuarter = lastQuarter;
24
+ exports.nextQuarter = nextQuarter;
4
25
  function todayRange(now = new Date()) {
5
26
  const start = new Date(now);
6
27
  start.setHours(0, 0, 0, 0);
@@ -8,33 +29,33 @@ function todayRange(now = new Date()) {
8
29
  end.setDate(end.getDate() + 1);
9
30
  return { start, end };
10
31
  }
11
- export function today(now = new Date()) { return todayRange(now); }
12
- export function yesterday(now = new Date()) {
32
+ function today(now = new Date()) { return todayRange(now); }
33
+ function yesterday(now = new Date()) {
13
34
  const t = todayRange(now);
14
35
  const end = new Date(t.start); // yesterday end equals today start
15
36
  const start = new Date(end);
16
37
  start.setDate(start.getDate() - 1);
17
38
  return { start, end };
18
39
  }
19
- export function tomorrow(now = new Date()) {
40
+ function tomorrow(now = new Date()) {
20
41
  const t = todayRange(now);
21
42
  t.start.setDate(t.start.getDate() + 1);
22
43
  t.end.setDate(t.end.getDate() + 1);
23
44
  return t;
24
45
  }
25
- export function lastNDays(n, now = new Date()) {
46
+ function lastNDays(n, now = new Date()) {
26
47
  const end = new Date(now);
27
48
  const start = new Date(end);
28
49
  start.setDate(start.getDate() - n);
29
50
  return { start, end };
30
51
  }
31
- export function nextNDays(n, now = new Date()) {
52
+ function nextNDays(n, now = new Date()) {
32
53
  const start = new Date(now);
33
54
  const end = new Date(start);
34
55
  end.setDate(end.getDate() + n);
35
56
  return { start, end };
36
57
  }
37
- export function thisWeek(now = new Date()) {
58
+ function thisWeek(now = new Date()) {
38
59
  const start = new Date(now);
39
60
  const day = start.getDay(); // 0 Sunday
40
61
  start.setHours(0, 0, 0, 0);
@@ -43,78 +64,78 @@ export function thisWeek(now = new Date()) {
43
64
  end.setDate(end.getDate() + 7);
44
65
  return { start, end };
45
66
  }
46
- export function lastWeek(now = new Date()) {
67
+ function lastWeek(now = new Date()) {
47
68
  const w = thisWeek(now);
48
69
  w.start.setDate(w.start.getDate() - 7);
49
70
  w.end.setDate(w.end.getDate() - 7);
50
71
  return w;
51
72
  }
52
- export function nextWeek(now = new Date()) {
73
+ function nextWeek(now = new Date()) {
53
74
  const w = thisWeek(now);
54
75
  w.start.setDate(w.start.getDate() + 7);
55
76
  w.end.setDate(w.end.getDate() + 7);
56
77
  return w;
57
78
  }
58
- export function thisMonth(now = new Date()) {
79
+ function thisMonth(now = new Date()) {
59
80
  const start = new Date(now.getFullYear(), now.getMonth(), 1);
60
81
  const end = new Date(now.getFullYear(), now.getMonth() + 1, 1);
61
82
  return { start, end };
62
83
  }
63
- export function lastMonth(now = new Date()) {
84
+ function lastMonth(now = new Date()) {
64
85
  const m = thisMonth(now);
65
86
  m.start.setMonth(m.start.getMonth() - 1);
66
87
  m.end.setMonth(m.end.getMonth() - 1);
67
88
  return m;
68
89
  }
69
- export function nextMonth(now = new Date()) {
90
+ function nextMonth(now = new Date()) {
70
91
  const m = thisMonth(now);
71
92
  m.start.setMonth(m.start.getMonth() + 1);
72
93
  m.end.setMonth(m.end.getMonth() + 1);
73
94
  return m;
74
95
  }
75
- export function thisYear(now = new Date()) {
96
+ function thisYear(now = new Date()) {
76
97
  const start = new Date(now.getFullYear(), 0, 1);
77
98
  const end = new Date(now.getFullYear() + 1, 0, 1);
78
99
  return { start, end };
79
100
  }
80
- export function lastYear(now = new Date()) {
101
+ function lastYear(now = new Date()) {
81
102
  const y = thisYear(now);
82
103
  y.start.setFullYear(y.start.getFullYear() - 1);
83
104
  y.end.setFullYear(y.end.getFullYear() - 1);
84
105
  return y;
85
106
  }
86
- export function nextYear(now = new Date()) {
107
+ function nextYear(now = new Date()) {
87
108
  const y = thisYear(now);
88
109
  y.start.setFullYear(y.start.getFullYear() + 1);
89
110
  y.end.setFullYear(y.end.getFullYear() + 1);
90
111
  return y;
91
112
  }
92
- export function rollingWindowDays(days, now = new Date()) {
113
+ function rollingWindowDays(days, now = new Date()) {
93
114
  const end = new Date(now);
94
115
  const start = new Date(end);
95
116
  start.setDate(start.getDate() - days);
96
117
  return { start, end };
97
118
  }
98
- export function quarterRange(now = new Date()) {
119
+ function quarterRange(now = new Date()) {
99
120
  const q = Math.floor(now.getMonth() / 3); // 0-3
100
121
  const start = new Date(now.getFullYear(), q * 3, 1);
101
122
  const end = new Date(now.getFullYear(), q * 3 + 3, 1);
102
123
  return { start, end };
103
124
  }
104
- export function lastQuarter(now = new Date()) {
125
+ function lastQuarter(now = new Date()) {
105
126
  const q = quarterRange(now);
106
127
  q.start.setMonth(q.start.getMonth() - 3);
107
128
  q.end.setMonth(q.end.getMonth() - 3);
108
129
  return q;
109
130
  }
110
- export function nextQuarter(now = new Date()) {
131
+ function nextQuarter(now = new Date()) {
111
132
  const q = quarterRange(now);
112
133
  q.start.setMonth(q.start.getMonth() + 3);
113
134
  q.end.setMonth(q.end.getMonth() + 3);
114
135
  return q;
115
136
  }
116
137
  /** Map of preset functions for dynamic access */
117
- export const RANGE_PRESETS = {
138
+ exports.RANGE_PRESETS = {
118
139
  today, yesterday, tomorrow,
119
140
  last7Days: (now) => lastNDays(7, now),
120
141
  last30Days: (now) => lastNDays(30, now),