ts-time-utils 4.1.0 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +83 -32
  2. package/dist/{age.js → age.cjs} +14 -6
  3. package/dist/{calculate.js → calculate.cjs} +42 -18
  4. package/dist/calculate.d.ts +7 -0
  5. package/dist/calculate.d.ts.map +1 -1
  6. package/dist/{calendar.js → calendar.cjs} +80 -39
  7. package/dist/{calendars.js → calendars.cjs} +48 -23
  8. package/dist/{chain.js → chain.cjs} +41 -40
  9. package/dist/{compare.js → compare.cjs} +58 -28
  10. package/dist/constants.cjs +19 -0
  11. package/dist/{countdown.js → countdown.cjs} +16 -7
  12. package/dist/{cron.js → cron.cjs} +20 -9
  13. package/dist/{dateRange.js → dateRange.cjs} +42 -26
  14. package/dist/{duration.js → duration.cjs} +56 -44
  15. package/dist/esm/calculate.d.ts +7 -0
  16. package/dist/esm/calculate.d.ts.map +1 -1
  17. package/dist/esm/calculate.js +11 -0
  18. package/dist/esm/chain.js +0 -5
  19. package/dist/esm/format.d.ts.map +1 -1
  20. package/dist/esm/format.js +3 -3
  21. package/dist/esm/index.d.ts +1 -1
  22. package/dist/esm/index.d.ts.map +1 -1
  23. package/dist/esm/index.js +1 -1
  24. package/dist/esm/naturalLanguage.d.ts +1 -3
  25. package/dist/esm/naturalLanguage.d.ts.map +1 -1
  26. package/dist/esm/naturalLanguage.js +9 -2
  27. package/dist/esm/plugins.d.ts +0 -6
  28. package/dist/esm/plugins.d.ts.map +1 -1
  29. package/dist/esm/plugins.js +36 -42
  30. package/dist/esm/recurrence.d.ts.map +1 -1
  31. package/dist/esm/recurrence.js +3 -5
  32. package/dist/esm/timezone.d.ts +6 -1
  33. package/dist/esm/timezone.d.ts.map +1 -1
  34. package/dist/esm/timezone.js +106 -66
  35. package/dist/esm/types.d.ts +0 -4
  36. package/dist/esm/types.d.ts.map +1 -1
  37. package/dist/{finance.js → finance.cjs} +39 -22
  38. package/dist/{fiscal.js → fiscal.cjs} +36 -17
  39. package/dist/{format.js → format.cjs} +85 -72
  40. package/dist/format.d.ts.map +1 -1
  41. package/dist/{healthcare.js → healthcare.cjs} +37 -22
  42. package/dist/{holidays.js → holidays.cjs} +52 -25
  43. package/dist/index.cjs +596 -0
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/{interval.js → interval.cjs} +24 -11
  47. package/dist/{iterate.js → iterate.cjs} +84 -41
  48. package/dist/{locale.js → locale.cjs} +54 -26
  49. package/dist/{naturalLanguage.js → naturalLanguage.cjs} +36 -23
  50. package/dist/naturalLanguage.d.ts +1 -3
  51. package/dist/naturalLanguage.d.ts.map +1 -1
  52. package/dist/{parse.js → parse.cjs} +24 -11
  53. package/dist/{performance.js → performance.cjs} +23 -10
  54. package/dist/{plugins.js → plugins.cjs} +48 -47
  55. package/dist/plugins.d.ts +0 -6
  56. package/dist/plugins.d.ts.map +1 -1
  57. package/dist/{precision.js → precision.cjs} +74 -37
  58. package/dist/{rangePresets.js → rangePresets.cjs} +40 -19
  59. package/dist/{recurrence.js → recurrence.cjs} +27 -21
  60. package/dist/recurrence.d.ts.map +1 -1
  61. package/dist/{scheduling.js → scheduling.cjs} +46 -31
  62. package/dist/{serialize.js → serialize.cjs} +36 -17
  63. package/dist/{temporal.js → temporal.cjs} +28 -13
  64. package/dist/{timezone.js → timezone.cjs} +140 -82
  65. package/dist/timezone.d.ts +6 -1
  66. package/dist/timezone.d.ts.map +1 -1
  67. package/dist/{types.js → types.cjs} +9 -3
  68. package/dist/types.d.ts +0 -4
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/{validate.js → validate.cjs} +54 -26
  71. package/dist/{workingHours.js → workingHours.cjs} +36 -17
  72. package/package.json +41 -38
  73. package/dist/constants.js +0 -16
  74. package/dist/index.js +0 -72
@@ -1,10 +1,24 @@
1
- import { MILLISECONDS_PER_SECOND, MILLISECONDS_PER_MINUTE, MILLISECONDS_PER_HOUR, MILLISECONDS_PER_DAY, MILLISECONDS_PER_WEEK, MILLISECONDS_PER_MONTH, MILLISECONDS_PER_YEAR } from './constants.js';
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatDuration = formatDuration;
4
+ exports.timeAgo = timeAgo;
5
+ exports.formatTime = formatTime;
6
+ exports.parseDuration = parseDuration;
7
+ exports.formatDate = formatDate;
8
+ exports.formatRelativeTime = formatRelativeTime;
9
+ exports.formatDateRange = formatDateRange;
10
+ exports.formatOrdinal = formatOrdinal;
11
+ exports.formatDayOrdinal = formatDayOrdinal;
12
+ exports.formatDurationCompact = formatDurationCompact;
13
+ exports.formatCalendarDate = formatCalendarDate;
14
+ const constants_js_1 = require("./constants.cjs");
15
+ const calculate_js_1 = require("./calculate.cjs");
2
16
  /**
3
17
  * Convert milliseconds to a human-readable duration.
4
18
  * @param ms - milliseconds
5
19
  * @param options - formatting options
6
20
  */
7
- export function formatDuration(ms, options = {}) {
21
+ function formatDuration(ms, options = {}) {
8
22
  const { includeMs = false, short = false, maxUnits = 2, round = false } = options;
9
23
  if (ms < 0)
10
24
  return '0' + (short ? 's' : ' seconds');
@@ -12,46 +26,46 @@ export function formatDuration(ms, options = {}) {
12
26
  const parts = [];
13
27
  let remaining = ms;
14
28
  // Years
15
- if (remaining >= MILLISECONDS_PER_YEAR) {
16
- const years = mathFn(remaining / MILLISECONDS_PER_YEAR);
29
+ if (remaining >= constants_js_1.MILLISECONDS_PER_YEAR) {
30
+ const years = mathFn(remaining / constants_js_1.MILLISECONDS_PER_YEAR);
17
31
  parts.push(years + (short ? 'y' : ` year${years !== 1 ? 's' : ''}`));
18
- remaining %= MILLISECONDS_PER_YEAR;
32
+ remaining %= constants_js_1.MILLISECONDS_PER_YEAR;
19
33
  }
20
34
  // Months
21
- if (remaining >= MILLISECONDS_PER_MONTH && parts.length < maxUnits) {
22
- const months = mathFn(remaining / MILLISECONDS_PER_MONTH);
35
+ if (remaining >= constants_js_1.MILLISECONDS_PER_MONTH && parts.length < maxUnits) {
36
+ const months = mathFn(remaining / constants_js_1.MILLISECONDS_PER_MONTH);
23
37
  parts.push(months + (short ? 'mo' : ` month${months !== 1 ? 's' : ''}`));
24
- remaining %= MILLISECONDS_PER_MONTH;
38
+ remaining %= constants_js_1.MILLISECONDS_PER_MONTH;
25
39
  }
26
40
  // Weeks
27
- if (remaining >= MILLISECONDS_PER_WEEK && parts.length < maxUnits) {
28
- const weeks = mathFn(remaining / MILLISECONDS_PER_WEEK);
41
+ if (remaining >= constants_js_1.MILLISECONDS_PER_WEEK && parts.length < maxUnits) {
42
+ const weeks = mathFn(remaining / constants_js_1.MILLISECONDS_PER_WEEK);
29
43
  parts.push(weeks + (short ? 'w' : ` week${weeks !== 1 ? 's' : ''}`));
30
- remaining %= MILLISECONDS_PER_WEEK;
44
+ remaining %= constants_js_1.MILLISECONDS_PER_WEEK;
31
45
  }
32
46
  // Days
33
- if (remaining >= MILLISECONDS_PER_DAY && parts.length < maxUnits) {
34
- const days = mathFn(remaining / MILLISECONDS_PER_DAY);
47
+ if (remaining >= constants_js_1.MILLISECONDS_PER_DAY && parts.length < maxUnits) {
48
+ const days = mathFn(remaining / constants_js_1.MILLISECONDS_PER_DAY);
35
49
  parts.push(days + (short ? 'd' : ` day${days !== 1 ? 's' : ''}`));
36
- remaining %= MILLISECONDS_PER_DAY;
50
+ remaining %= constants_js_1.MILLISECONDS_PER_DAY;
37
51
  }
38
52
  // Hours
39
- if (remaining >= MILLISECONDS_PER_HOUR && parts.length < maxUnits) {
40
- const hours = mathFn(remaining / MILLISECONDS_PER_HOUR);
53
+ if (remaining >= constants_js_1.MILLISECONDS_PER_HOUR && parts.length < maxUnits) {
54
+ const hours = mathFn(remaining / constants_js_1.MILLISECONDS_PER_HOUR);
41
55
  parts.push(hours + (short ? 'h' : ` hour${hours !== 1 ? 's' : ''}`));
42
- remaining %= MILLISECONDS_PER_HOUR;
56
+ remaining %= constants_js_1.MILLISECONDS_PER_HOUR;
43
57
  }
44
58
  // Minutes
45
- if (remaining >= MILLISECONDS_PER_MINUTE && parts.length < maxUnits) {
46
- const minutes = mathFn(remaining / MILLISECONDS_PER_MINUTE);
59
+ if (remaining >= constants_js_1.MILLISECONDS_PER_MINUTE && parts.length < maxUnits) {
60
+ const minutes = mathFn(remaining / constants_js_1.MILLISECONDS_PER_MINUTE);
47
61
  parts.push(minutes + (short ? 'm' : ` minute${minutes !== 1 ? 's' : ''}`));
48
- remaining %= MILLISECONDS_PER_MINUTE;
62
+ remaining %= constants_js_1.MILLISECONDS_PER_MINUTE;
49
63
  }
50
64
  // Seconds
51
- if (remaining >= MILLISECONDS_PER_SECOND && parts.length < maxUnits) {
52
- const seconds = mathFn(remaining / MILLISECONDS_PER_SECOND);
65
+ if (remaining >= constants_js_1.MILLISECONDS_PER_SECOND && parts.length < maxUnits) {
66
+ const seconds = mathFn(remaining / constants_js_1.MILLISECONDS_PER_SECOND);
53
67
  parts.push(seconds + (short ? 's' : ` second${seconds !== 1 ? 's' : ''}`));
54
- remaining %= MILLISECONDS_PER_SECOND;
68
+ remaining %= constants_js_1.MILLISECONDS_PER_SECOND;
55
69
  }
56
70
  // Milliseconds
57
71
  if ((remaining > 0 || parts.length === 0) && includeMs && parts.length < maxUnits) {
@@ -68,43 +82,43 @@ export function formatDuration(ms, options = {}) {
68
82
  * @param date - past or future date
69
83
  * @param options - formatting options
70
84
  */
71
- export function timeAgo(date, options = {}) {
85
+ function timeAgo(date, options = {}) {
72
86
  const now = new Date();
73
87
  const diffMs = now.getTime() - date.getTime();
74
88
  const { short = false } = options;
75
89
  const isFuture = diffMs < 0;
76
90
  const absDiffMs = Math.abs(diffMs);
77
- if (absDiffMs < MILLISECONDS_PER_MINUTE) {
78
- const seconds = Math.floor(absDiffMs / MILLISECONDS_PER_SECOND);
91
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_MINUTE) {
92
+ const seconds = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_SECOND);
79
93
  const unit = short ? 's' : ` second${seconds !== 1 ? 's' : ''}`;
80
94
  return isFuture ? `in ${seconds}${unit}` : `${seconds}${unit} ago`;
81
95
  }
82
- if (absDiffMs < MILLISECONDS_PER_HOUR) {
83
- const minutes = Math.floor(absDiffMs / MILLISECONDS_PER_MINUTE);
96
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_HOUR) {
97
+ const minutes = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_MINUTE);
84
98
  const unit = short ? 'm' : ` minute${minutes !== 1 ? 's' : ''}`;
85
99
  return isFuture ? `in ${minutes}${unit}` : `${minutes}${unit} ago`;
86
100
  }
87
- if (absDiffMs < MILLISECONDS_PER_DAY) {
88
- const hours = Math.floor(absDiffMs / MILLISECONDS_PER_HOUR);
101
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_DAY) {
102
+ const hours = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_HOUR);
89
103
  const unit = short ? 'h' : ` hour${hours !== 1 ? 's' : ''}`;
90
104
  return isFuture ? `in ${hours}${unit}` : `${hours}${unit} ago`;
91
105
  }
92
- if (absDiffMs < MILLISECONDS_PER_WEEK) {
93
- const days = Math.floor(absDiffMs / MILLISECONDS_PER_DAY);
106
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_WEEK) {
107
+ const days = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_DAY);
94
108
  const unit = short ? 'd' : ` day${days !== 1 ? 's' : ''}`;
95
109
  return isFuture ? `in ${days}${unit}` : `${days}${unit} ago`;
96
110
  }
97
- if (absDiffMs < MILLISECONDS_PER_MONTH) {
98
- const weeks = Math.floor(absDiffMs / MILLISECONDS_PER_WEEK);
111
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_MONTH) {
112
+ const weeks = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_WEEK);
99
113
  const unit = short ? 'w' : ` week${weeks !== 1 ? 's' : ''}`;
100
114
  return isFuture ? `in ${weeks}${unit}` : `${weeks}${unit} ago`;
101
115
  }
102
- if (absDiffMs < MILLISECONDS_PER_YEAR) {
103
- const months = Math.floor(absDiffMs / MILLISECONDS_PER_MONTH);
116
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_YEAR) {
117
+ const months = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_MONTH);
104
118
  const unit = short ? 'mo' : ` month${months !== 1 ? 's' : ''}`;
105
119
  return isFuture ? `in ${months}${unit}` : `${months}${unit} ago`;
106
120
  }
107
- const years = Math.floor(absDiffMs / MILLISECONDS_PER_YEAR);
121
+ const years = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_YEAR);
108
122
  const unit = short ? 'y' : ` year${years !== 1 ? 's' : ''}`;
109
123
  return isFuture ? `in ${years}${unit}` : `${years}${unit} ago`;
110
124
  }
@@ -113,7 +127,7 @@ export function timeAgo(date, options = {}) {
113
127
  * @param date - date to format
114
128
  * @param format - format type
115
129
  */
116
- export function formatTime(date, format = '24h') {
130
+ function formatTime(date, format = '24h') {
117
131
  switch (format) {
118
132
  case '12h':
119
133
  return date.toLocaleTimeString('en-US', {
@@ -132,7 +146,7 @@ export function formatTime(date, format = '24h') {
132
146
  * Parse a duration string like "1h 30m" into milliseconds
133
147
  * @param duration - duration string (e.g., "1h 30m", "2d", "45s")
134
148
  */
135
- export function parseDuration(duration) {
149
+ function parseDuration(duration) {
136
150
  const regex = /(\d+(?:\.\d+)?)\s*([a-zA-Z]+)/g;
137
151
  let totalMs = 0;
138
152
  let match;
@@ -149,39 +163,39 @@ export function parseDuration(duration) {
149
163
  case 'sec':
150
164
  case 'second':
151
165
  case 'seconds':
152
- totalMs += value * MILLISECONDS_PER_SECOND;
166
+ totalMs += value * constants_js_1.MILLISECONDS_PER_SECOND;
153
167
  break;
154
168
  case 'm':
155
169
  case 'min':
156
170
  case 'minute':
157
171
  case 'minutes':
158
- totalMs += value * MILLISECONDS_PER_MINUTE;
172
+ totalMs += value * constants_js_1.MILLISECONDS_PER_MINUTE;
159
173
  break;
160
174
  case 'h':
161
175
  case 'hr':
162
176
  case 'hour':
163
177
  case 'hours':
164
- totalMs += value * MILLISECONDS_PER_HOUR;
178
+ totalMs += value * constants_js_1.MILLISECONDS_PER_HOUR;
165
179
  break;
166
180
  case 'd':
167
181
  case 'day':
168
182
  case 'days':
169
- totalMs += value * MILLISECONDS_PER_DAY;
183
+ totalMs += value * constants_js_1.MILLISECONDS_PER_DAY;
170
184
  break;
171
185
  case 'w':
172
186
  case 'week':
173
187
  case 'weeks':
174
- totalMs += value * MILLISECONDS_PER_WEEK;
188
+ totalMs += value * constants_js_1.MILLISECONDS_PER_WEEK;
175
189
  break;
176
190
  case 'mo':
177
191
  case 'month':
178
192
  case 'months':
179
- totalMs += value * MILLISECONDS_PER_MONTH;
193
+ totalMs += value * constants_js_1.MILLISECONDS_PER_MONTH;
180
194
  break;
181
195
  case 'y':
182
196
  case 'year':
183
197
  case 'years':
184
- totalMs += value * MILLISECONDS_PER_YEAR;
198
+ totalMs += value * constants_js_1.MILLISECONDS_PER_YEAR;
185
199
  break;
186
200
  }
187
201
  }
@@ -225,7 +239,7 @@ const DAY_NAMES_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
225
239
  * - A: AM/PM
226
240
  * - a: am/pm
227
241
  */
228
- export function formatDate(date, pattern) {
242
+ function formatDate(date, pattern) {
229
243
  const year = date.getFullYear();
230
244
  const month = date.getMonth();
231
245
  const day = date.getDate();
@@ -270,36 +284,36 @@ export function formatDate(date, pattern) {
270
284
  * @param date - target date
271
285
  * @param baseDate - base date (default: now)
272
286
  */
273
- export function formatRelativeTime(date, baseDate = new Date()) {
287
+ function formatRelativeTime(date, baseDate = new Date()) {
274
288
  const diffMs = date.getTime() - baseDate.getTime();
275
289
  const isFuture = diffMs > 0;
276
290
  const absDiffMs = Math.abs(diffMs);
277
291
  const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
278
- if (absDiffMs < MILLISECONDS_PER_MINUTE) {
279
- const seconds = Math.round(absDiffMs / MILLISECONDS_PER_SECOND);
292
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_MINUTE) {
293
+ const seconds = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_SECOND);
280
294
  return rtf.format(isFuture ? seconds : -seconds, 'second');
281
295
  }
282
- if (absDiffMs < MILLISECONDS_PER_HOUR) {
283
- const minutes = Math.round(absDiffMs / MILLISECONDS_PER_MINUTE);
296
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_HOUR) {
297
+ const minutes = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_MINUTE);
284
298
  return rtf.format(isFuture ? minutes : -minutes, 'minute');
285
299
  }
286
- if (absDiffMs < MILLISECONDS_PER_DAY) {
287
- const hours = Math.round(absDiffMs / MILLISECONDS_PER_HOUR);
300
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_DAY) {
301
+ const hours = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_HOUR);
288
302
  return rtf.format(isFuture ? hours : -hours, 'hour');
289
303
  }
290
- if (absDiffMs < MILLISECONDS_PER_WEEK) {
291
- const days = Math.round(absDiffMs / MILLISECONDS_PER_DAY);
304
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_WEEK) {
305
+ const days = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_DAY);
292
306
  return rtf.format(isFuture ? days : -days, 'day');
293
307
  }
294
- if (absDiffMs < MILLISECONDS_PER_MONTH) {
295
- const weeks = Math.round(absDiffMs / MILLISECONDS_PER_WEEK);
308
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_MONTH) {
309
+ const weeks = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_WEEK);
296
310
  return rtf.format(isFuture ? weeks : -weeks, 'week');
297
311
  }
298
- if (absDiffMs < MILLISECONDS_PER_YEAR) {
299
- const months = Math.round(absDiffMs / MILLISECONDS_PER_MONTH);
312
+ if (absDiffMs < constants_js_1.MILLISECONDS_PER_YEAR) {
313
+ const months = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_MONTH);
300
314
  return rtf.format(isFuture ? months : -months, 'month');
301
315
  }
302
- const years = Math.round(absDiffMs / MILLISECONDS_PER_YEAR);
316
+ const years = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_YEAR);
303
317
  return rtf.format(isFuture ? years : -years, 'year');
304
318
  }
305
319
  /**
@@ -308,7 +322,7 @@ export function formatRelativeTime(date, baseDate = new Date()) {
308
322
  * @param end - end date
309
323
  * @param options - formatting options
310
324
  */
311
- export function formatDateRange(start, end, options = {}) {
325
+ function formatDateRange(start, end, options = {}) {
312
326
  const { separator = ' - ', includeTime = false, format = 'medium' } = options;
313
327
  const sameYear = start.getFullYear() === end.getFullYear();
314
328
  const sameMonth = sameYear && start.getMonth() === end.getMonth();
@@ -335,7 +349,7 @@ export function formatDateRange(start, end, options = {}) {
335
349
  * Format a number as an ordinal (1st, 2nd, 3rd, etc.)
336
350
  * @param n - number to format
337
351
  */
338
- export function formatOrdinal(n) {
352
+ function formatOrdinal(n) {
339
353
  const suffixes = ['th', 'st', 'nd', 'rd'];
340
354
  const v = n % 100;
341
355
  return n + (suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0]);
@@ -344,7 +358,7 @@ export function formatOrdinal(n) {
344
358
  * Format a day of month as an ordinal (1st, 2nd, 3rd, etc.)
345
359
  * @param date - date to format
346
360
  */
347
- export function formatDayOrdinal(date) {
361
+ function formatDayOrdinal(date) {
348
362
  return formatOrdinal(date.getDate());
349
363
  }
350
364
  /**
@@ -352,10 +366,10 @@ export function formatDayOrdinal(date) {
352
366
  * @param ms - milliseconds
353
367
  * @param showHours - always show hours even if 0
354
368
  */
355
- export function formatDurationCompact(ms, showHours = true) {
356
- const hours = Math.floor(ms / MILLISECONDS_PER_HOUR);
357
- const minutes = Math.floor((ms % MILLISECONDS_PER_HOUR) / MILLISECONDS_PER_MINUTE);
358
- const seconds = Math.floor((ms % MILLISECONDS_PER_MINUTE) / MILLISECONDS_PER_SECOND);
369
+ function formatDurationCompact(ms, showHours = true) {
370
+ const hours = Math.floor(ms / constants_js_1.MILLISECONDS_PER_HOUR);
371
+ const minutes = Math.floor((ms % constants_js_1.MILLISECONDS_PER_HOUR) / constants_js_1.MILLISECONDS_PER_MINUTE);
372
+ const seconds = Math.floor((ms % constants_js_1.MILLISECONDS_PER_MINUTE) / constants_js_1.MILLISECONDS_PER_SECOND);
359
373
  const pad = (n) => String(n).padStart(2, '0');
360
374
  if (showHours || hours > 0) {
361
375
  return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
@@ -366,11 +380,10 @@ export function formatDurationCompact(ms, showHours = true) {
366
380
  * Format a date/time for display in a calendar
367
381
  * @param date - date to format
368
382
  */
369
- export function formatCalendarDate(date) {
383
+ function formatCalendarDate(date) {
370
384
  const now = new Date();
371
- const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
372
- const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
373
- const diffDays = Math.round((dateOnly.getTime() - today.getTime()) / MILLISECONDS_PER_DAY);
385
+ const dayDistance = (0, calculate_js_1.differenceInCalendarDays)(date, now);
386
+ const diffDays = date.getTime() >= now.getTime() ? dayDistance : -dayDistance;
374
387
  if (diffDays === 0)
375
388
  return 'Today';
376
389
  if (diffDays === -1)
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,aAAa,EACd,MAAM,gBAAgB,CAAC;AAGxB;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA2E9E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA+CvE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,KAAK,GAAG,KAAK,GAAG,KAAa,GAAG,MAAM,CAcpF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyDtD;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA4C9D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAE,IAAiB,GAAG,MAAM,CAuClF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,EACX,GAAG,EAAE,IAAI,EACT,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACjC,GACL,MAAM,CA6BR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,GAAE,OAAc,GAAG,MAAM,CAYnF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAwBrD"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,aAAa,EACd,MAAM,gBAAgB,CAAC;AAIxB;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA2E9E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA+CvE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,KAAK,GAAG,KAAK,GAAG,KAAa,GAAG,MAAM,CAcpF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyDtD;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA4C9D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAE,IAAiB,GAAG,MAAM,CAuClF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,EACX,GAAG,EAAE,IAAI,EACT,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACjC,GACL,MAAM,CA6BR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,GAAE,OAAc,GAAG,MAAM,CAYnF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAuBrD"}
@@ -1,15 +1,30 @@
1
+ "use strict";
1
2
  /**
2
3
  * @fileoverview Healthcare utilities for medical scheduling and compliance timing
3
4
  * Provides medication schedules, shift patterns, on-call rotations, and compliance windows
4
5
  */
5
- import { Duration } from './duration.js';
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.DEFAULT_MEDICATION_CONFIG = exports.SHIFT_DURATIONS = exports.MEDICATION_FREQUENCIES = void 0;
8
+ exports.getMedicationTimes = getMedicationTimes;
9
+ exports.getNextMedicationTime = getNextMedicationTime;
10
+ exports.parseMedicationFrequency = parseMedicationFrequency;
11
+ exports.generateShiftSchedule = generateShiftSchedule;
12
+ exports.getShiftForTime = getShiftForTime;
13
+ exports.isOnShift = isOnShift;
14
+ exports.createOnCallRotation = createOnCallRotation;
15
+ exports.getOnCallStaff = getOnCallStaff;
16
+ exports.isWithinComplianceWindow = isWithinComplianceWindow;
17
+ exports.getComplianceDeadline = getComplianceDeadline;
18
+ exports.timeUntilDeadline = timeUntilDeadline;
19
+ exports.calculateRestBetweenShifts = calculateRestBetweenShifts;
20
+ const duration_js_1 = require("./duration.cjs");
6
21
  // ============================================================================
7
22
  // Constants
8
23
  // ============================================================================
9
24
  /**
10
25
  * Number of doses per day for each frequency
11
26
  */
12
- export const MEDICATION_FREQUENCIES = {
27
+ exports.MEDICATION_FREQUENCIES = {
13
28
  'QD': 1,
14
29
  'BID': 2,
15
30
  'TID': 3,
@@ -23,7 +38,7 @@ export const MEDICATION_FREQUENCIES = {
23
38
  /**
24
39
  * Hours per shift pattern
25
40
  */
26
- export const SHIFT_DURATIONS = {
41
+ exports.SHIFT_DURATIONS = {
27
42
  '8hr': 8,
28
43
  '12hr': 12,
29
44
  '24hr': 24
@@ -31,7 +46,7 @@ export const SHIFT_DURATIONS = {
31
46
  /**
32
47
  * Default medication timing config
33
48
  */
34
- export const DEFAULT_MEDICATION_CONFIG = {
49
+ exports.DEFAULT_MEDICATION_CONFIG = {
35
50
  wakeTime: '07:00',
36
51
  sleepTime: '22:00',
37
52
  withMeals: false
@@ -76,10 +91,10 @@ function setTimeOnDate(date, hour, minute) {
76
91
  * // Returns [6:00 AM, 1:30 PM, 9:00 PM] (three times daily)
77
92
  * ```
78
93
  */
79
- export function getMedicationTimes(date, frequency, config) {
94
+ function getMedicationTimes(date, frequency, config) {
80
95
  const d = toDate(date);
81
- const cfg = { ...DEFAULT_MEDICATION_CONFIG, ...config };
82
- const doses = MEDICATION_FREQUENCIES[frequency];
96
+ const cfg = { ...exports.DEFAULT_MEDICATION_CONFIG, ...config };
97
+ const doses = exports.MEDICATION_FREQUENCIES[frequency];
83
98
  if (doses === null) {
84
99
  return []; // PRN - as needed
85
100
  }
@@ -125,7 +140,7 @@ export function getMedicationTimes(date, frequency, config) {
125
140
  * // Returns 7:00 PM on same day (next BID dose after 10 AM)
126
141
  * ```
127
142
  */
128
- export function getNextMedicationTime(after, frequency, config) {
143
+ function getNextMedicationTime(after, frequency, config) {
129
144
  if (frequency === 'PRN') {
130
145
  return null;
131
146
  }
@@ -156,7 +171,7 @@ export function getNextMedicationTime(after, frequency, config) {
156
171
  * parseMedicationFrequency('invalid'); // null
157
172
  * ```
158
173
  */
159
- export function parseMedicationFrequency(freq) {
174
+ function parseMedicationFrequency(freq) {
160
175
  const normalized = freq.toLowerCase();
161
176
  const mapping = {
162
177
  'qd': 'QD',
@@ -202,10 +217,10 @@ export function parseMedicationFrequency(freq) {
202
217
  * // Returns 4 shifts: day/night on 15th, day/night on 16th
203
218
  * ```
204
219
  */
205
- export function generateShiftSchedule(start, end, config) {
220
+ function generateShiftSchedule(start, end, config) {
206
221
  const startDate = toDate(start);
207
222
  const endDate = toDate(end);
208
- const shiftHours = SHIFT_DURATIONS[config.pattern];
223
+ const shiftHours = exports.SHIFT_DURATIONS[config.pattern];
209
224
  const shiftsPerDay = 24 / shiftHours;
210
225
  const shifts = [];
211
226
  const current = new Date(startDate.getTime());
@@ -241,9 +256,9 @@ export function generateShiftSchedule(start, end, config) {
241
256
  * // Returns { start: 7:00 AM, end: 3:00 PM } (day shift)
242
257
  * ```
243
258
  */
244
- export function getShiftForTime(date, config) {
259
+ function getShiftForTime(date, config) {
245
260
  const d = toDate(date);
246
- const shiftHours = SHIFT_DURATIONS[config.pattern];
261
+ const shiftHours = exports.SHIFT_DURATIONS[config.pattern];
247
262
  const shiftMs = shiftHours * 60 * 60 * 1000;
248
263
  // Find the shift start that contains this time
249
264
  const dayStart = new Date(d.getTime());
@@ -277,10 +292,10 @@ export function getShiftForTime(date, config) {
277
292
  * ); // true (10 AM is during 7 AM - 3 PM shift)
278
293
  * ```
279
294
  */
280
- export function isOnShift(date, shiftStart, config) {
295
+ function isOnShift(date, shiftStart, config) {
281
296
  const d = toDate(date);
282
297
  const start = toDate(shiftStart);
283
- const shiftHours = SHIFT_DURATIONS[config.pattern];
298
+ const shiftHours = exports.SHIFT_DURATIONS[config.pattern];
284
299
  const shiftEnd = new Date(start.getTime() + shiftHours * 60 * 60 * 1000);
285
300
  return d.getTime() >= start.getTime() && d.getTime() < shiftEnd.getTime();
286
301
  }
@@ -307,7 +322,7 @@ export function isOnShift(date, shiftStart, config) {
307
322
  * // Returns 3 slots, one per doctor per day
308
323
  * ```
309
324
  */
310
- export function createOnCallRotation(start, end, staff, hoursPerShift = 24) {
325
+ function createOnCallRotation(start, end, staff, hoursPerShift = 24) {
311
326
  if (staff.length === 0) {
312
327
  return [];
313
328
  }
@@ -343,7 +358,7 @@ export function createOnCallRotation(start, end, staff, hoursPerShift = 24) {
343
358
  * // Returns 'Dr. Jones' (whoever is on call at 3 AM on the 16th)
344
359
  * ```
345
360
  */
346
- export function getOnCallStaff(date, rotation) {
361
+ function getOnCallStaff(date, rotation) {
347
362
  const d = toDate(date);
348
363
  for (const slot of rotation) {
349
364
  if (d.getTime() >= slot.start.getTime() && d.getTime() < slot.end.getTime()) {
@@ -370,7 +385,7 @@ export function getOnCallStaff(date, rotation) {
370
385
  * ); // true (event occurred before deadline)
371
386
  * ```
372
387
  */
373
- export function isWithinComplianceWindow(event, deadline) {
388
+ function isWithinComplianceWindow(event, deadline) {
374
389
  const eventDate = toDate(event);
375
390
  const deadlineDate = toDate(deadline);
376
391
  return eventDate.getTime() <= deadlineDate.getTime();
@@ -391,7 +406,7 @@ export function isWithinComplianceWindow(event, deadline) {
391
406
  * // Returns 2024-01-18T08:00:00 (72 hours later)
392
407
  * ```
393
408
  */
394
- export function getComplianceDeadline(event, windowHours) {
409
+ function getComplianceDeadline(event, windowHours) {
395
410
  const eventDate = toDate(event);
396
411
  return new Date(eventDate.getTime() + windowHours * 60 * 60 * 1000);
397
412
  }
@@ -411,14 +426,14 @@ export function getComplianceDeadline(event, windowHours) {
411
426
  * // Returns Duration of 24 hours
412
427
  * ```
413
428
  */
414
- export function timeUntilDeadline(event, deadline) {
429
+ function timeUntilDeadline(event, deadline) {
415
430
  const eventDate = toDate(event);
416
431
  const deadlineDate = toDate(deadline);
417
432
  const diff = deadlineDate.getTime() - eventDate.getTime();
418
433
  if (diff < 0) {
419
434
  return null; // Already past deadline
420
435
  }
421
- return Duration.fromMilliseconds(diff);
436
+ return duration_js_1.Duration.fromMilliseconds(diff);
422
437
  }
423
438
  // ============================================================================
424
439
  // Utility Functions
@@ -439,7 +454,7 @@ export function timeUntilDeadline(event, deadline) {
439
454
  * // Returns 12 (hours of rest)
440
455
  * ```
441
456
  */
442
- export function calculateRestBetweenShifts(shift1End, shift2Start) {
457
+ function calculateRestBetweenShifts(shift1End, shift2Start) {
443
458
  const end = toDate(shift1End);
444
459
  const start = toDate(shift2Start);
445
460
  const diffMs = start.getTime() - end.getTime();