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.
- package/README.md +81 -31
- package/dist/{age.js → age.cjs} +14 -6
- package/dist/{calculate.js → calculate.cjs} +30 -18
- package/dist/{calendar.js → calendar.cjs} +80 -39
- package/dist/{calendars.js → calendars.cjs} +48 -23
- package/dist/{chain.js → chain.cjs} +41 -40
- package/dist/{compare.js → compare.cjs} +58 -28
- package/dist/constants.cjs +19 -0
- package/dist/{countdown.js → countdown.cjs} +16 -7
- package/dist/{cron.js → cron.cjs} +20 -9
- package/dist/{dateRange.js → dateRange.cjs} +42 -26
- package/dist/{duration.js → duration.cjs} +56 -44
- package/dist/esm/chain.js +0 -5
- package/dist/esm/naturalLanguage.d.ts +1 -3
- package/dist/esm/naturalLanguage.d.ts.map +1 -1
- package/dist/esm/naturalLanguage.js +9 -2
- package/dist/esm/plugins.d.ts +0 -6
- package/dist/esm/plugins.d.ts.map +1 -1
- package/dist/esm/plugins.js +36 -42
- package/dist/esm/recurrence.d.ts.map +1 -1
- package/dist/esm/recurrence.js +3 -5
- package/dist/esm/timezone.d.ts +6 -1
- package/dist/esm/timezone.d.ts.map +1 -1
- package/dist/esm/timezone.js +106 -66
- package/dist/esm/types.d.ts +0 -4
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/{finance.js → finance.cjs} +39 -22
- package/dist/{fiscal.js → fiscal.cjs} +36 -17
- package/dist/{format.js → format.cjs} +83 -70
- package/dist/{healthcare.js → healthcare.cjs} +37 -22
- package/dist/{holidays.js → holidays.cjs} +52 -25
- package/dist/index.cjs +595 -0
- package/dist/{interval.js → interval.cjs} +24 -11
- package/dist/{iterate.js → iterate.cjs} +84 -41
- package/dist/{locale.js → locale.cjs} +54 -26
- package/dist/{naturalLanguage.js → naturalLanguage.cjs} +36 -23
- package/dist/naturalLanguage.d.ts +1 -3
- package/dist/naturalLanguage.d.ts.map +1 -1
- package/dist/{parse.js → parse.cjs} +24 -11
- package/dist/{performance.js → performance.cjs} +23 -10
- package/dist/{plugins.js → plugins.cjs} +48 -47
- package/dist/plugins.d.ts +0 -6
- package/dist/plugins.d.ts.map +1 -1
- package/dist/{precision.js → precision.cjs} +74 -37
- package/dist/{rangePresets.js → rangePresets.cjs} +40 -19
- package/dist/{recurrence.js → recurrence.cjs} +27 -21
- package/dist/recurrence.d.ts.map +1 -1
- package/dist/{scheduling.js → scheduling.cjs} +46 -31
- package/dist/{serialize.js → serialize.cjs} +36 -17
- package/dist/{temporal.js → temporal.cjs} +28 -13
- package/dist/{timezone.js → timezone.cjs} +140 -82
- package/dist/timezone.d.ts +6 -1
- package/dist/timezone.d.ts.map +1 -1
- package/dist/{types.js → types.cjs} +9 -3
- package/dist/types.d.ts +0 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/{validate.js → validate.cjs} +54 -26
- package/dist/{workingHours.js → workingHours.cjs} +36 -17
- package/package.json +40 -37
- package/dist/constants.js +0 -16
- package/dist/index.js +0 -72
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @fileoverview Fiscal year and accounting period utilities
|
|
3
4
|
* Supports configurable fiscal year start months for business calculations
|
|
4
5
|
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.FISCAL_PRESETS = void 0;
|
|
8
|
+
exports.getFiscalYear = getFiscalYear;
|
|
9
|
+
exports.getFiscalQuarter = getFiscalQuarter;
|
|
10
|
+
exports.getFiscalYearStart = getFiscalYearStart;
|
|
11
|
+
exports.getFiscalYearEnd = getFiscalYearEnd;
|
|
12
|
+
exports.getFiscalQuarterStart = getFiscalQuarterStart;
|
|
13
|
+
exports.getFiscalQuarterEnd = getFiscalQuarterEnd;
|
|
14
|
+
exports.isSameFiscalYear = isSameFiscalYear;
|
|
15
|
+
exports.isSameFiscalQuarter = isSameFiscalQuarter;
|
|
16
|
+
exports.getFiscalMonth = getFiscalMonth;
|
|
17
|
+
exports.getDaysRemainingInFiscalYear = getDaysRemainingInFiscalYear;
|
|
18
|
+
exports.getDaysElapsedInFiscalYear = getDaysElapsedInFiscalYear;
|
|
19
|
+
exports.getFiscalYearProgress = getFiscalYearProgress;
|
|
20
|
+
exports.getFiscalWeek = getFiscalWeek;
|
|
21
|
+
exports.formatFiscalYear = formatFiscalYear;
|
|
22
|
+
exports.formatFiscalQuarter = formatFiscalQuarter;
|
|
23
|
+
exports.getFiscalPeriodInfo = getFiscalPeriodInfo;
|
|
5
24
|
const DEFAULT_CONFIG = {
|
|
6
25
|
startMonth: 1, // January (calendar year)
|
|
7
26
|
};
|
|
@@ -22,7 +41,7 @@ const DEFAULT_CONFIG = {
|
|
|
22
41
|
* getFiscalYear(new Date('2024-06-15'), { startMonth: 7 }) // 2023
|
|
23
42
|
* getFiscalYear(new Date('2024-07-15'), { startMonth: 7 }) // 2024
|
|
24
43
|
*/
|
|
25
|
-
|
|
44
|
+
function getFiscalYear(date, config = {}) {
|
|
26
45
|
const { startMonth } = { ...DEFAULT_CONFIG, ...config };
|
|
27
46
|
const month = date.getMonth() + 1; // 1-12
|
|
28
47
|
const year = date.getFullYear();
|
|
@@ -47,7 +66,7 @@ export function getFiscalYear(date, config = {}) {
|
|
|
47
66
|
* getFiscalQuarter(new Date('2024-04-15'), { startMonth: 4 }) // 1
|
|
48
67
|
* getFiscalQuarter(new Date('2024-07-15'), { startMonth: 4 }) // 2
|
|
49
68
|
*/
|
|
50
|
-
|
|
69
|
+
function getFiscalQuarter(date, config = {}) {
|
|
51
70
|
const { startMonth } = { ...DEFAULT_CONFIG, ...config };
|
|
52
71
|
const month = date.getMonth() + 1; // 1-12
|
|
53
72
|
// Calculate months since fiscal year start
|
|
@@ -67,7 +86,7 @@ export function getFiscalQuarter(date, config = {}) {
|
|
|
67
86
|
* getFiscalYearStart(2024, { startMonth: 4 }) // 2024-04-01 (FY2024 starts Apr 2024)
|
|
68
87
|
* getFiscalYearStart(2024, { startMonth: 7 }) // 2024-07-01 (FY2024 starts Jul 2024)
|
|
69
88
|
*/
|
|
70
|
-
|
|
89
|
+
function getFiscalYearStart(fiscalYear, config = {}) {
|
|
71
90
|
const { startMonth } = { ...DEFAULT_CONFIG, ...config };
|
|
72
91
|
// Fiscal year N starts in the startMonth of calendar year N
|
|
73
92
|
return new Date(fiscalYear, startMonth - 1, 1);
|
|
@@ -82,7 +101,7 @@ export function getFiscalYearStart(fiscalYear, config = {}) {
|
|
|
82
101
|
* getFiscalYearEnd(2024, { startMonth: 4 }) // 2025-03-31 (FY2024 ends Mar 2025)
|
|
83
102
|
* getFiscalYearEnd(2024, { startMonth: 7 }) // 2025-06-30 (FY2024 ends Jun 2025)
|
|
84
103
|
*/
|
|
85
|
-
|
|
104
|
+
function getFiscalYearEnd(fiscalYear, config = {}) {
|
|
86
105
|
const { startMonth } = { ...DEFAULT_CONFIG, ...config };
|
|
87
106
|
if (startMonth === 1) {
|
|
88
107
|
return new Date(fiscalYear, 11, 31, 23, 59, 59, 999);
|
|
@@ -107,7 +126,7 @@ export function getFiscalYearEnd(fiscalYear, config = {}) {
|
|
|
107
126
|
* getFiscalQuarterStart(2024, 1, { startMonth: 4 }) // 2023-04-01
|
|
108
127
|
* getFiscalQuarterStart(2024, 2, { startMonth: 4 }) // 2023-07-01
|
|
109
128
|
*/
|
|
110
|
-
|
|
129
|
+
function getFiscalQuarterStart(fiscalYear, quarter, config = {}) {
|
|
111
130
|
if (quarter < 1 || quarter > 4) {
|
|
112
131
|
throw new Error('Quarter must be between 1 and 4');
|
|
113
132
|
}
|
|
@@ -129,7 +148,7 @@ export function getFiscalQuarterStart(fiscalYear, quarter, config = {}) {
|
|
|
129
148
|
* getFiscalQuarterEnd(2024, 2) // 2024-06-30
|
|
130
149
|
* getFiscalQuarterEnd(2024, 1, { startMonth: 4 }) // 2023-06-30
|
|
131
150
|
*/
|
|
132
|
-
|
|
151
|
+
function getFiscalQuarterEnd(fiscalYear, quarter, config = {}) {
|
|
133
152
|
if (quarter < 1 || quarter > 4) {
|
|
134
153
|
throw new Error('Quarter must be between 1 and 4');
|
|
135
154
|
}
|
|
@@ -146,7 +165,7 @@ export function getFiscalQuarterEnd(fiscalYear, quarter, config = {}) {
|
|
|
146
165
|
* @param config - Fiscal year configuration
|
|
147
166
|
* @returns True if both dates are in the same fiscal year
|
|
148
167
|
*/
|
|
149
|
-
|
|
168
|
+
function isSameFiscalYear(date1, date2, config = {}) {
|
|
150
169
|
return getFiscalYear(date1, config) === getFiscalYear(date2, config);
|
|
151
170
|
}
|
|
152
171
|
/**
|
|
@@ -156,7 +175,7 @@ export function isSameFiscalYear(date1, date2, config = {}) {
|
|
|
156
175
|
* @param config - Fiscal year configuration
|
|
157
176
|
* @returns True if both dates are in the same fiscal year and quarter
|
|
158
177
|
*/
|
|
159
|
-
|
|
178
|
+
function isSameFiscalQuarter(date1, date2, config = {}) {
|
|
160
179
|
return (getFiscalYear(date1, config) === getFiscalYear(date2, config) &&
|
|
161
180
|
getFiscalQuarter(date1, config) === getFiscalQuarter(date2, config));
|
|
162
181
|
}
|
|
@@ -170,7 +189,7 @@ export function isSameFiscalQuarter(date1, date2, config = {}) {
|
|
|
170
189
|
* getFiscalMonth(new Date('2024-04-15'), { startMonth: 4 }) // 1
|
|
171
190
|
* getFiscalMonth(new Date('2024-03-15'), { startMonth: 4 }) // 12
|
|
172
191
|
*/
|
|
173
|
-
|
|
192
|
+
function getFiscalMonth(date, config = {}) {
|
|
174
193
|
const { startMonth } = { ...DEFAULT_CONFIG, ...config };
|
|
175
194
|
const month = date.getMonth() + 1; // 1-12
|
|
176
195
|
let fiscalMonth = month - startMonth + 1;
|
|
@@ -185,7 +204,7 @@ export function getFiscalMonth(date, config = {}) {
|
|
|
185
204
|
* @param config - Fiscal year configuration
|
|
186
205
|
* @returns Number of days remaining in the fiscal year
|
|
187
206
|
*/
|
|
188
|
-
|
|
207
|
+
function getDaysRemainingInFiscalYear(date, config = {}) {
|
|
189
208
|
const fiscalYear = getFiscalYear(date, config);
|
|
190
209
|
const fyEnd = getFiscalYearEnd(fiscalYear, config);
|
|
191
210
|
const startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
@@ -198,7 +217,7 @@ export function getDaysRemainingInFiscalYear(date, config = {}) {
|
|
|
198
217
|
* @param config - Fiscal year configuration
|
|
199
218
|
* @returns Number of days elapsed in the fiscal year (including the given date)
|
|
200
219
|
*/
|
|
201
|
-
|
|
220
|
+
function getDaysElapsedInFiscalYear(date, config = {}) {
|
|
202
221
|
const fiscalYear = getFiscalYear(date, config);
|
|
203
222
|
const fyStart = getFiscalYearStart(fiscalYear, config);
|
|
204
223
|
const startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
@@ -211,7 +230,7 @@ export function getDaysElapsedInFiscalYear(date, config = {}) {
|
|
|
211
230
|
* @param config - Fiscal year configuration
|
|
212
231
|
* @returns Percentage of fiscal year completed (0-100)
|
|
213
232
|
*/
|
|
214
|
-
|
|
233
|
+
function getFiscalYearProgress(date, config = {}) {
|
|
215
234
|
const fiscalYear = getFiscalYear(date, config);
|
|
216
235
|
const fyStart = getFiscalYearStart(fiscalYear, config);
|
|
217
236
|
const fyEnd = getFiscalYearEnd(fiscalYear, config);
|
|
@@ -225,14 +244,14 @@ export function getFiscalYearProgress(date, config = {}) {
|
|
|
225
244
|
* @param config - Fiscal year configuration
|
|
226
245
|
* @returns The fiscal week number
|
|
227
246
|
*/
|
|
228
|
-
|
|
247
|
+
function getFiscalWeek(date, config = {}) {
|
|
229
248
|
const elapsed = getDaysElapsedInFiscalYear(date, config);
|
|
230
249
|
return Math.ceil(elapsed / 7);
|
|
231
250
|
}
|
|
232
251
|
/**
|
|
233
252
|
* Common fiscal year configurations
|
|
234
253
|
*/
|
|
235
|
-
|
|
254
|
+
exports.FISCAL_PRESETS = {
|
|
236
255
|
/** Calendar year (January start) - Default */
|
|
237
256
|
CALENDAR: { startMonth: 1 },
|
|
238
257
|
/** UK/India government fiscal year (April start) */
|
|
@@ -249,7 +268,7 @@ export const FISCAL_PRESETS = {
|
|
|
249
268
|
* @param format - Format style: 'short' (FY2024) or 'long' (FY2023/24)
|
|
250
269
|
* @returns Formatted fiscal year string
|
|
251
270
|
*/
|
|
252
|
-
|
|
271
|
+
function formatFiscalYear(fiscalYear, config = {}, format = 'short') {
|
|
253
272
|
const { startMonth } = { ...DEFAULT_CONFIG, ...config };
|
|
254
273
|
if (format === 'short' || startMonth === 1) {
|
|
255
274
|
return `FY${fiscalYear}`;
|
|
@@ -266,7 +285,7 @@ export function formatFiscalYear(fiscalYear, config = {}, format = 'short') {
|
|
|
266
285
|
* @param config - Fiscal year configuration
|
|
267
286
|
* @returns Formatted fiscal quarter string
|
|
268
287
|
*/
|
|
269
|
-
|
|
288
|
+
function formatFiscalQuarter(fiscalYear, quarter, config = {}) {
|
|
270
289
|
const fyString = formatFiscalYear(fiscalYear, config, 'short');
|
|
271
290
|
return `Q${quarter} ${fyString}`;
|
|
272
291
|
}
|
|
@@ -276,7 +295,7 @@ export function formatFiscalQuarter(fiscalYear, quarter, config = {}) {
|
|
|
276
295
|
* @param config - Fiscal year configuration
|
|
277
296
|
* @returns Object with fiscal period information
|
|
278
297
|
*/
|
|
279
|
-
|
|
298
|
+
function getFiscalPeriodInfo(date, config = {}) {
|
|
280
299
|
const fiscalYear = getFiscalYear(date, config);
|
|
281
300
|
const fiscalQuarter = getFiscalQuarter(date, config);
|
|
282
301
|
return {
|
|
@@ -1,10 +1,23 @@
|
|
|
1
|
-
|
|
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");
|
|
2
15
|
/**
|
|
3
16
|
* Convert milliseconds to a human-readable duration.
|
|
4
17
|
* @param ms - milliseconds
|
|
5
18
|
* @param options - formatting options
|
|
6
19
|
*/
|
|
7
|
-
|
|
20
|
+
function formatDuration(ms, options = {}) {
|
|
8
21
|
const { includeMs = false, short = false, maxUnits = 2, round = false } = options;
|
|
9
22
|
if (ms < 0)
|
|
10
23
|
return '0' + (short ? 's' : ' seconds');
|
|
@@ -12,46 +25,46 @@ export function formatDuration(ms, options = {}) {
|
|
|
12
25
|
const parts = [];
|
|
13
26
|
let remaining = ms;
|
|
14
27
|
// Years
|
|
15
|
-
if (remaining >= MILLISECONDS_PER_YEAR) {
|
|
16
|
-
const years = mathFn(remaining / MILLISECONDS_PER_YEAR);
|
|
28
|
+
if (remaining >= constants_js_1.MILLISECONDS_PER_YEAR) {
|
|
29
|
+
const years = mathFn(remaining / constants_js_1.MILLISECONDS_PER_YEAR);
|
|
17
30
|
parts.push(years + (short ? 'y' : ` year${years !== 1 ? 's' : ''}`));
|
|
18
|
-
remaining %= MILLISECONDS_PER_YEAR;
|
|
31
|
+
remaining %= constants_js_1.MILLISECONDS_PER_YEAR;
|
|
19
32
|
}
|
|
20
33
|
// Months
|
|
21
|
-
if (remaining >= MILLISECONDS_PER_MONTH && parts.length < maxUnits) {
|
|
22
|
-
const months = mathFn(remaining / MILLISECONDS_PER_MONTH);
|
|
34
|
+
if (remaining >= constants_js_1.MILLISECONDS_PER_MONTH && parts.length < maxUnits) {
|
|
35
|
+
const months = mathFn(remaining / constants_js_1.MILLISECONDS_PER_MONTH);
|
|
23
36
|
parts.push(months + (short ? 'mo' : ` month${months !== 1 ? 's' : ''}`));
|
|
24
|
-
remaining %= MILLISECONDS_PER_MONTH;
|
|
37
|
+
remaining %= constants_js_1.MILLISECONDS_PER_MONTH;
|
|
25
38
|
}
|
|
26
39
|
// Weeks
|
|
27
|
-
if (remaining >= MILLISECONDS_PER_WEEK && parts.length < maxUnits) {
|
|
28
|
-
const weeks = mathFn(remaining / MILLISECONDS_PER_WEEK);
|
|
40
|
+
if (remaining >= constants_js_1.MILLISECONDS_PER_WEEK && parts.length < maxUnits) {
|
|
41
|
+
const weeks = mathFn(remaining / constants_js_1.MILLISECONDS_PER_WEEK);
|
|
29
42
|
parts.push(weeks + (short ? 'w' : ` week${weeks !== 1 ? 's' : ''}`));
|
|
30
|
-
remaining %= MILLISECONDS_PER_WEEK;
|
|
43
|
+
remaining %= constants_js_1.MILLISECONDS_PER_WEEK;
|
|
31
44
|
}
|
|
32
45
|
// Days
|
|
33
|
-
if (remaining >= MILLISECONDS_PER_DAY && parts.length < maxUnits) {
|
|
34
|
-
const days = mathFn(remaining / MILLISECONDS_PER_DAY);
|
|
46
|
+
if (remaining >= constants_js_1.MILLISECONDS_PER_DAY && parts.length < maxUnits) {
|
|
47
|
+
const days = mathFn(remaining / constants_js_1.MILLISECONDS_PER_DAY);
|
|
35
48
|
parts.push(days + (short ? 'd' : ` day${days !== 1 ? 's' : ''}`));
|
|
36
|
-
remaining %= MILLISECONDS_PER_DAY;
|
|
49
|
+
remaining %= constants_js_1.MILLISECONDS_PER_DAY;
|
|
37
50
|
}
|
|
38
51
|
// Hours
|
|
39
|
-
if (remaining >= MILLISECONDS_PER_HOUR && parts.length < maxUnits) {
|
|
40
|
-
const hours = mathFn(remaining / MILLISECONDS_PER_HOUR);
|
|
52
|
+
if (remaining >= constants_js_1.MILLISECONDS_PER_HOUR && parts.length < maxUnits) {
|
|
53
|
+
const hours = mathFn(remaining / constants_js_1.MILLISECONDS_PER_HOUR);
|
|
41
54
|
parts.push(hours + (short ? 'h' : ` hour${hours !== 1 ? 's' : ''}`));
|
|
42
|
-
remaining %= MILLISECONDS_PER_HOUR;
|
|
55
|
+
remaining %= constants_js_1.MILLISECONDS_PER_HOUR;
|
|
43
56
|
}
|
|
44
57
|
// Minutes
|
|
45
|
-
if (remaining >= MILLISECONDS_PER_MINUTE && parts.length < maxUnits) {
|
|
46
|
-
const minutes = mathFn(remaining / MILLISECONDS_PER_MINUTE);
|
|
58
|
+
if (remaining >= constants_js_1.MILLISECONDS_PER_MINUTE && parts.length < maxUnits) {
|
|
59
|
+
const minutes = mathFn(remaining / constants_js_1.MILLISECONDS_PER_MINUTE);
|
|
47
60
|
parts.push(minutes + (short ? 'm' : ` minute${minutes !== 1 ? 's' : ''}`));
|
|
48
|
-
remaining %= MILLISECONDS_PER_MINUTE;
|
|
61
|
+
remaining %= constants_js_1.MILLISECONDS_PER_MINUTE;
|
|
49
62
|
}
|
|
50
63
|
// Seconds
|
|
51
|
-
if (remaining >= MILLISECONDS_PER_SECOND && parts.length < maxUnits) {
|
|
52
|
-
const seconds = mathFn(remaining / MILLISECONDS_PER_SECOND);
|
|
64
|
+
if (remaining >= constants_js_1.MILLISECONDS_PER_SECOND && parts.length < maxUnits) {
|
|
65
|
+
const seconds = mathFn(remaining / constants_js_1.MILLISECONDS_PER_SECOND);
|
|
53
66
|
parts.push(seconds + (short ? 's' : ` second${seconds !== 1 ? 's' : ''}`));
|
|
54
|
-
remaining %= MILLISECONDS_PER_SECOND;
|
|
67
|
+
remaining %= constants_js_1.MILLISECONDS_PER_SECOND;
|
|
55
68
|
}
|
|
56
69
|
// Milliseconds
|
|
57
70
|
if ((remaining > 0 || parts.length === 0) && includeMs && parts.length < maxUnits) {
|
|
@@ -68,43 +81,43 @@ export function formatDuration(ms, options = {}) {
|
|
|
68
81
|
* @param date - past or future date
|
|
69
82
|
* @param options - formatting options
|
|
70
83
|
*/
|
|
71
|
-
|
|
84
|
+
function timeAgo(date, options = {}) {
|
|
72
85
|
const now = new Date();
|
|
73
86
|
const diffMs = now.getTime() - date.getTime();
|
|
74
87
|
const { short = false } = options;
|
|
75
88
|
const isFuture = diffMs < 0;
|
|
76
89
|
const absDiffMs = Math.abs(diffMs);
|
|
77
|
-
if (absDiffMs < MILLISECONDS_PER_MINUTE) {
|
|
78
|
-
const seconds = Math.floor(absDiffMs / MILLISECONDS_PER_SECOND);
|
|
90
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_MINUTE) {
|
|
91
|
+
const seconds = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_SECOND);
|
|
79
92
|
const unit = short ? 's' : ` second${seconds !== 1 ? 's' : ''}`;
|
|
80
93
|
return isFuture ? `in ${seconds}${unit}` : `${seconds}${unit} ago`;
|
|
81
94
|
}
|
|
82
|
-
if (absDiffMs < MILLISECONDS_PER_HOUR) {
|
|
83
|
-
const minutes = Math.floor(absDiffMs / MILLISECONDS_PER_MINUTE);
|
|
95
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_HOUR) {
|
|
96
|
+
const minutes = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_MINUTE);
|
|
84
97
|
const unit = short ? 'm' : ` minute${minutes !== 1 ? 's' : ''}`;
|
|
85
98
|
return isFuture ? `in ${minutes}${unit}` : `${minutes}${unit} ago`;
|
|
86
99
|
}
|
|
87
|
-
if (absDiffMs < MILLISECONDS_PER_DAY) {
|
|
88
|
-
const hours = Math.floor(absDiffMs / MILLISECONDS_PER_HOUR);
|
|
100
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_DAY) {
|
|
101
|
+
const hours = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_HOUR);
|
|
89
102
|
const unit = short ? 'h' : ` hour${hours !== 1 ? 's' : ''}`;
|
|
90
103
|
return isFuture ? `in ${hours}${unit}` : `${hours}${unit} ago`;
|
|
91
104
|
}
|
|
92
|
-
if (absDiffMs < MILLISECONDS_PER_WEEK) {
|
|
93
|
-
const days = Math.floor(absDiffMs / MILLISECONDS_PER_DAY);
|
|
105
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_WEEK) {
|
|
106
|
+
const days = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_DAY);
|
|
94
107
|
const unit = short ? 'd' : ` day${days !== 1 ? 's' : ''}`;
|
|
95
108
|
return isFuture ? `in ${days}${unit}` : `${days}${unit} ago`;
|
|
96
109
|
}
|
|
97
|
-
if (absDiffMs < MILLISECONDS_PER_MONTH) {
|
|
98
|
-
const weeks = Math.floor(absDiffMs / MILLISECONDS_PER_WEEK);
|
|
110
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_MONTH) {
|
|
111
|
+
const weeks = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_WEEK);
|
|
99
112
|
const unit = short ? 'w' : ` week${weeks !== 1 ? 's' : ''}`;
|
|
100
113
|
return isFuture ? `in ${weeks}${unit}` : `${weeks}${unit} ago`;
|
|
101
114
|
}
|
|
102
|
-
if (absDiffMs < MILLISECONDS_PER_YEAR) {
|
|
103
|
-
const months = Math.floor(absDiffMs / MILLISECONDS_PER_MONTH);
|
|
115
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_YEAR) {
|
|
116
|
+
const months = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_MONTH);
|
|
104
117
|
const unit = short ? 'mo' : ` month${months !== 1 ? 's' : ''}`;
|
|
105
118
|
return isFuture ? `in ${months}${unit}` : `${months}${unit} ago`;
|
|
106
119
|
}
|
|
107
|
-
const years = Math.floor(absDiffMs / MILLISECONDS_PER_YEAR);
|
|
120
|
+
const years = Math.floor(absDiffMs / constants_js_1.MILLISECONDS_PER_YEAR);
|
|
108
121
|
const unit = short ? 'y' : ` year${years !== 1 ? 's' : ''}`;
|
|
109
122
|
return isFuture ? `in ${years}${unit}` : `${years}${unit} ago`;
|
|
110
123
|
}
|
|
@@ -113,7 +126,7 @@ export function timeAgo(date, options = {}) {
|
|
|
113
126
|
* @param date - date to format
|
|
114
127
|
* @param format - format type
|
|
115
128
|
*/
|
|
116
|
-
|
|
129
|
+
function formatTime(date, format = '24h') {
|
|
117
130
|
switch (format) {
|
|
118
131
|
case '12h':
|
|
119
132
|
return date.toLocaleTimeString('en-US', {
|
|
@@ -132,7 +145,7 @@ export function formatTime(date, format = '24h') {
|
|
|
132
145
|
* Parse a duration string like "1h 30m" into milliseconds
|
|
133
146
|
* @param duration - duration string (e.g., "1h 30m", "2d", "45s")
|
|
134
147
|
*/
|
|
135
|
-
|
|
148
|
+
function parseDuration(duration) {
|
|
136
149
|
const regex = /(\d+(?:\.\d+)?)\s*([a-zA-Z]+)/g;
|
|
137
150
|
let totalMs = 0;
|
|
138
151
|
let match;
|
|
@@ -149,39 +162,39 @@ export function parseDuration(duration) {
|
|
|
149
162
|
case 'sec':
|
|
150
163
|
case 'second':
|
|
151
164
|
case 'seconds':
|
|
152
|
-
totalMs += value * MILLISECONDS_PER_SECOND;
|
|
165
|
+
totalMs += value * constants_js_1.MILLISECONDS_PER_SECOND;
|
|
153
166
|
break;
|
|
154
167
|
case 'm':
|
|
155
168
|
case 'min':
|
|
156
169
|
case 'minute':
|
|
157
170
|
case 'minutes':
|
|
158
|
-
totalMs += value * MILLISECONDS_PER_MINUTE;
|
|
171
|
+
totalMs += value * constants_js_1.MILLISECONDS_PER_MINUTE;
|
|
159
172
|
break;
|
|
160
173
|
case 'h':
|
|
161
174
|
case 'hr':
|
|
162
175
|
case 'hour':
|
|
163
176
|
case 'hours':
|
|
164
|
-
totalMs += value * MILLISECONDS_PER_HOUR;
|
|
177
|
+
totalMs += value * constants_js_1.MILLISECONDS_PER_HOUR;
|
|
165
178
|
break;
|
|
166
179
|
case 'd':
|
|
167
180
|
case 'day':
|
|
168
181
|
case 'days':
|
|
169
|
-
totalMs += value * MILLISECONDS_PER_DAY;
|
|
182
|
+
totalMs += value * constants_js_1.MILLISECONDS_PER_DAY;
|
|
170
183
|
break;
|
|
171
184
|
case 'w':
|
|
172
185
|
case 'week':
|
|
173
186
|
case 'weeks':
|
|
174
|
-
totalMs += value * MILLISECONDS_PER_WEEK;
|
|
187
|
+
totalMs += value * constants_js_1.MILLISECONDS_PER_WEEK;
|
|
175
188
|
break;
|
|
176
189
|
case 'mo':
|
|
177
190
|
case 'month':
|
|
178
191
|
case 'months':
|
|
179
|
-
totalMs += value * MILLISECONDS_PER_MONTH;
|
|
192
|
+
totalMs += value * constants_js_1.MILLISECONDS_PER_MONTH;
|
|
180
193
|
break;
|
|
181
194
|
case 'y':
|
|
182
195
|
case 'year':
|
|
183
196
|
case 'years':
|
|
184
|
-
totalMs += value * MILLISECONDS_PER_YEAR;
|
|
197
|
+
totalMs += value * constants_js_1.MILLISECONDS_PER_YEAR;
|
|
185
198
|
break;
|
|
186
199
|
}
|
|
187
200
|
}
|
|
@@ -225,7 +238,7 @@ const DAY_NAMES_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
|
225
238
|
* - A: AM/PM
|
|
226
239
|
* - a: am/pm
|
|
227
240
|
*/
|
|
228
|
-
|
|
241
|
+
function formatDate(date, pattern) {
|
|
229
242
|
const year = date.getFullYear();
|
|
230
243
|
const month = date.getMonth();
|
|
231
244
|
const day = date.getDate();
|
|
@@ -270,36 +283,36 @@ export function formatDate(date, pattern) {
|
|
|
270
283
|
* @param date - target date
|
|
271
284
|
* @param baseDate - base date (default: now)
|
|
272
285
|
*/
|
|
273
|
-
|
|
286
|
+
function formatRelativeTime(date, baseDate = new Date()) {
|
|
274
287
|
const diffMs = date.getTime() - baseDate.getTime();
|
|
275
288
|
const isFuture = diffMs > 0;
|
|
276
289
|
const absDiffMs = Math.abs(diffMs);
|
|
277
290
|
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
|
|
278
|
-
if (absDiffMs < MILLISECONDS_PER_MINUTE) {
|
|
279
|
-
const seconds = Math.round(absDiffMs / MILLISECONDS_PER_SECOND);
|
|
291
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_MINUTE) {
|
|
292
|
+
const seconds = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_SECOND);
|
|
280
293
|
return rtf.format(isFuture ? seconds : -seconds, 'second');
|
|
281
294
|
}
|
|
282
|
-
if (absDiffMs < MILLISECONDS_PER_HOUR) {
|
|
283
|
-
const minutes = Math.round(absDiffMs / MILLISECONDS_PER_MINUTE);
|
|
295
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_HOUR) {
|
|
296
|
+
const minutes = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_MINUTE);
|
|
284
297
|
return rtf.format(isFuture ? minutes : -minutes, 'minute');
|
|
285
298
|
}
|
|
286
|
-
if (absDiffMs < MILLISECONDS_PER_DAY) {
|
|
287
|
-
const hours = Math.round(absDiffMs / MILLISECONDS_PER_HOUR);
|
|
299
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_DAY) {
|
|
300
|
+
const hours = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_HOUR);
|
|
288
301
|
return rtf.format(isFuture ? hours : -hours, 'hour');
|
|
289
302
|
}
|
|
290
|
-
if (absDiffMs < MILLISECONDS_PER_WEEK) {
|
|
291
|
-
const days = Math.round(absDiffMs / MILLISECONDS_PER_DAY);
|
|
303
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_WEEK) {
|
|
304
|
+
const days = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_DAY);
|
|
292
305
|
return rtf.format(isFuture ? days : -days, 'day');
|
|
293
306
|
}
|
|
294
|
-
if (absDiffMs < MILLISECONDS_PER_MONTH) {
|
|
295
|
-
const weeks = Math.round(absDiffMs / MILLISECONDS_PER_WEEK);
|
|
307
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_MONTH) {
|
|
308
|
+
const weeks = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_WEEK);
|
|
296
309
|
return rtf.format(isFuture ? weeks : -weeks, 'week');
|
|
297
310
|
}
|
|
298
|
-
if (absDiffMs < MILLISECONDS_PER_YEAR) {
|
|
299
|
-
const months = Math.round(absDiffMs / MILLISECONDS_PER_MONTH);
|
|
311
|
+
if (absDiffMs < constants_js_1.MILLISECONDS_PER_YEAR) {
|
|
312
|
+
const months = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_MONTH);
|
|
300
313
|
return rtf.format(isFuture ? months : -months, 'month');
|
|
301
314
|
}
|
|
302
|
-
const years = Math.round(absDiffMs / MILLISECONDS_PER_YEAR);
|
|
315
|
+
const years = Math.round(absDiffMs / constants_js_1.MILLISECONDS_PER_YEAR);
|
|
303
316
|
return rtf.format(isFuture ? years : -years, 'year');
|
|
304
317
|
}
|
|
305
318
|
/**
|
|
@@ -308,7 +321,7 @@ export function formatRelativeTime(date, baseDate = new Date()) {
|
|
|
308
321
|
* @param end - end date
|
|
309
322
|
* @param options - formatting options
|
|
310
323
|
*/
|
|
311
|
-
|
|
324
|
+
function formatDateRange(start, end, options = {}) {
|
|
312
325
|
const { separator = ' - ', includeTime = false, format = 'medium' } = options;
|
|
313
326
|
const sameYear = start.getFullYear() === end.getFullYear();
|
|
314
327
|
const sameMonth = sameYear && start.getMonth() === end.getMonth();
|
|
@@ -335,7 +348,7 @@ export function formatDateRange(start, end, options = {}) {
|
|
|
335
348
|
* Format a number as an ordinal (1st, 2nd, 3rd, etc.)
|
|
336
349
|
* @param n - number to format
|
|
337
350
|
*/
|
|
338
|
-
|
|
351
|
+
function formatOrdinal(n) {
|
|
339
352
|
const suffixes = ['th', 'st', 'nd', 'rd'];
|
|
340
353
|
const v = n % 100;
|
|
341
354
|
return n + (suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0]);
|
|
@@ -344,7 +357,7 @@ export function formatOrdinal(n) {
|
|
|
344
357
|
* Format a day of month as an ordinal (1st, 2nd, 3rd, etc.)
|
|
345
358
|
* @param date - date to format
|
|
346
359
|
*/
|
|
347
|
-
|
|
360
|
+
function formatDayOrdinal(date) {
|
|
348
361
|
return formatOrdinal(date.getDate());
|
|
349
362
|
}
|
|
350
363
|
/**
|
|
@@ -352,10 +365,10 @@ export function formatDayOrdinal(date) {
|
|
|
352
365
|
* @param ms - milliseconds
|
|
353
366
|
* @param showHours - always show hours even if 0
|
|
354
367
|
*/
|
|
355
|
-
|
|
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);
|
|
368
|
+
function formatDurationCompact(ms, showHours = true) {
|
|
369
|
+
const hours = Math.floor(ms / constants_js_1.MILLISECONDS_PER_HOUR);
|
|
370
|
+
const minutes = Math.floor((ms % constants_js_1.MILLISECONDS_PER_HOUR) / constants_js_1.MILLISECONDS_PER_MINUTE);
|
|
371
|
+
const seconds = Math.floor((ms % constants_js_1.MILLISECONDS_PER_MINUTE) / constants_js_1.MILLISECONDS_PER_SECOND);
|
|
359
372
|
const pad = (n) => String(n).padStart(2, '0');
|
|
360
373
|
if (showHours || hours > 0) {
|
|
361
374
|
return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
|
|
@@ -366,11 +379,11 @@ export function formatDurationCompact(ms, showHours = true) {
|
|
|
366
379
|
* Format a date/time for display in a calendar
|
|
367
380
|
* @param date - date to format
|
|
368
381
|
*/
|
|
369
|
-
|
|
382
|
+
function formatCalendarDate(date) {
|
|
370
383
|
const now = new Date();
|
|
371
384
|
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
372
385
|
const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
373
|
-
const diffDays = Math.round((dateOnly.getTime() - today.getTime()) / MILLISECONDS_PER_DAY);
|
|
386
|
+
const diffDays = Math.round((dateOnly.getTime() - today.getTime()) / constants_js_1.MILLISECONDS_PER_DAY);
|
|
374
387
|
if (diffDays === 0)
|
|
375
388
|
return 'Today';
|
|
376
389
|
if (diffDays === -1)
|