ts-time-utils 0.0.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.
- package/README.md +343 -0
- package/dist/age.d.ts +49 -0
- package/dist/age.d.ts.map +1 -0
- package/dist/age.js +106 -0
- package/dist/calculate.d.ts +49 -0
- package/dist/calculate.d.ts.map +1 -0
- package/dist/calculate.js +179 -0
- package/dist/calendar.d.ts +82 -0
- package/dist/calendar.d.ts.map +1 -0
- package/dist/calendar.js +154 -0
- package/dist/constants.d.ts +35 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +17 -0
- package/dist/esm/age.d.ts +49 -0
- package/dist/esm/age.d.ts.map +1 -0
- package/dist/esm/age.js +106 -0
- package/dist/esm/calculate.d.ts +49 -0
- package/dist/esm/calculate.d.ts.map +1 -0
- package/dist/esm/calculate.js +179 -0
- package/dist/esm/calendar.d.ts +82 -0
- package/dist/esm/calendar.d.ts.map +1 -0
- package/dist/esm/calendar.js +154 -0
- package/dist/esm/constants.d.ts +35 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.js +17 -0
- package/dist/esm/format.d.ts +25 -0
- package/dist/esm/format.d.ts.map +1 -0
- package/dist/esm/format.js +189 -0
- package/dist/esm/index.d.ts +17 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +28 -0
- package/dist/esm/interval.d.ts +30 -0
- package/dist/esm/interval.d.ts.map +1 -0
- package/dist/esm/interval.js +86 -0
- package/dist/esm/parse.d.ts +31 -0
- package/dist/esm/parse.d.ts.map +1 -0
- package/dist/esm/parse.js +217 -0
- package/dist/esm/performance.d.ts +110 -0
- package/dist/esm/performance.d.ts.map +1 -0
- package/dist/esm/performance.js +222 -0
- package/dist/esm/rangePresets.d.ts +45 -0
- package/dist/esm/rangePresets.d.ts.map +1 -0
- package/dist/esm/rangePresets.js +124 -0
- package/dist/esm/timezone.d.ts +38 -0
- package/dist/esm/timezone.d.ts.map +1 -0
- package/dist/esm/timezone.js +99 -0
- package/dist/esm/validate.d.ts +62 -0
- package/dist/esm/validate.d.ts.map +1 -0
- package/dist/esm/validate.js +108 -0
- package/dist/esm/workingHours.d.ts +25 -0
- package/dist/esm/workingHours.d.ts.map +1 -0
- package/dist/esm/workingHours.js +107 -0
- package/dist/format.d.ts +25 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +189 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/interval.d.ts +30 -0
- package/dist/interval.d.ts.map +1 -0
- package/dist/interval.js +86 -0
- package/dist/parse.d.ts +31 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +217 -0
- package/dist/performance.d.ts +110 -0
- package/dist/performance.d.ts.map +1 -0
- package/dist/performance.js +222 -0
- package/dist/rangePresets.d.ts +45 -0
- package/dist/rangePresets.d.ts.map +1 -0
- package/dist/rangePresets.js +124 -0
- package/dist/timezone.d.ts +38 -0
- package/dist/timezone.d.ts.map +1 -0
- package/dist/timezone.js +99 -0
- package/dist/validate.d.ts +62 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +108 -0
- package/dist/workingHours.d.ts +25 -0
- package/dist/workingHours.d.ts.map +1 -0
- package/dist/workingHours.js +107 -0
- package/package.json +102 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if a date is valid
|
|
3
|
+
* @param date - date to validate
|
|
4
|
+
*/
|
|
5
|
+
export declare function isValidDate(date: Date | string | number): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Check if a year is a leap year
|
|
8
|
+
* @param year - year to check
|
|
9
|
+
*/
|
|
10
|
+
export declare function isLeapYear(year: number): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Check if a date is in the past
|
|
13
|
+
* @param date - date to check
|
|
14
|
+
*/
|
|
15
|
+
export declare function isPast(date: Date): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a date is in the future
|
|
18
|
+
* @param date - date to check
|
|
19
|
+
*/
|
|
20
|
+
export declare function isFuture(date: Date): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a date is today
|
|
23
|
+
* @param date - date to check
|
|
24
|
+
*/
|
|
25
|
+
export declare function isToday(date: Date): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Check if a date is yesterday
|
|
28
|
+
* @param date - date to check
|
|
29
|
+
*/
|
|
30
|
+
export declare function isYesterday(date: Date): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Check if a date is tomorrow
|
|
33
|
+
* @param date - date to check
|
|
34
|
+
*/
|
|
35
|
+
export declare function isTomorrow(date: Date): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check if two dates are the same day
|
|
38
|
+
* @param date1 - first date
|
|
39
|
+
* @param date2 - second date
|
|
40
|
+
*/
|
|
41
|
+
export declare function isSameDay(date1: Date, date2: Date): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Check if a date is a weekend (Saturday or Sunday)
|
|
44
|
+
* @param date - date to check
|
|
45
|
+
*/
|
|
46
|
+
export declare function isWeekend(date: Date): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a date is a weekday (Monday through Friday)
|
|
49
|
+
* @param date - date to check
|
|
50
|
+
*/
|
|
51
|
+
export declare function isWeekday(date: Date): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Check if a time string is valid (HH:MM or HH:MM:SS format)
|
|
54
|
+
* @param time - time string to validate
|
|
55
|
+
*/
|
|
56
|
+
export declare function isValidTimeString(time: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a date string is valid ISO 8601 format
|
|
59
|
+
* @param dateString - date string to validate
|
|
60
|
+
*/
|
|
61
|
+
export declare function isValidISOString(dateString: string): boolean;
|
|
62
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAWjE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAE1C;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAE5C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAO3C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAQ/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAQ9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAM3D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG7C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAE7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAG5D"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if a date is valid
|
|
3
|
+
* @param date - date to validate
|
|
4
|
+
*/
|
|
5
|
+
export function isValidDate(date) {
|
|
6
|
+
if (date instanceof Date) {
|
|
7
|
+
return !isNaN(date.getTime());
|
|
8
|
+
}
|
|
9
|
+
if (typeof date === 'string' || typeof date === 'number') {
|
|
10
|
+
const parsed = new Date(date);
|
|
11
|
+
return !isNaN(parsed.getTime());
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Check if a year is a leap year
|
|
17
|
+
* @param year - year to check
|
|
18
|
+
*/
|
|
19
|
+
export function isLeapYear(year) {
|
|
20
|
+
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if a date is in the past
|
|
24
|
+
* @param date - date to check
|
|
25
|
+
*/
|
|
26
|
+
export function isPast(date) {
|
|
27
|
+
return date.getTime() < new Date().getTime();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if a date is in the future
|
|
31
|
+
* @param date - date to check
|
|
32
|
+
*/
|
|
33
|
+
export function isFuture(date) {
|
|
34
|
+
return date.getTime() > new Date().getTime();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if a date is today
|
|
38
|
+
* @param date - date to check
|
|
39
|
+
*/
|
|
40
|
+
export function isToday(date) {
|
|
41
|
+
const today = new Date();
|
|
42
|
+
return (date.getDate() === today.getDate() &&
|
|
43
|
+
date.getMonth() === today.getMonth() &&
|
|
44
|
+
date.getFullYear() === today.getFullYear());
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if a date is yesterday
|
|
48
|
+
* @param date - date to check
|
|
49
|
+
*/
|
|
50
|
+
export function isYesterday(date) {
|
|
51
|
+
const yesterday = new Date();
|
|
52
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
53
|
+
return (date.getDate() === yesterday.getDate() &&
|
|
54
|
+
date.getMonth() === yesterday.getMonth() &&
|
|
55
|
+
date.getFullYear() === yesterday.getFullYear());
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if a date is tomorrow
|
|
59
|
+
* @param date - date to check
|
|
60
|
+
*/
|
|
61
|
+
export function isTomorrow(date) {
|
|
62
|
+
const tomorrow = new Date();
|
|
63
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
64
|
+
return (date.getDate() === tomorrow.getDate() &&
|
|
65
|
+
date.getMonth() === tomorrow.getMonth() &&
|
|
66
|
+
date.getFullYear() === tomorrow.getFullYear());
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if two dates are the same day
|
|
70
|
+
* @param date1 - first date
|
|
71
|
+
* @param date2 - second date
|
|
72
|
+
*/
|
|
73
|
+
export function isSameDay(date1, date2) {
|
|
74
|
+
return (date1.getDate() === date2.getDate() &&
|
|
75
|
+
date1.getMonth() === date2.getMonth() &&
|
|
76
|
+
date1.getFullYear() === date2.getFullYear());
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if a date is a weekend (Saturday or Sunday)
|
|
80
|
+
* @param date - date to check
|
|
81
|
+
*/
|
|
82
|
+
export function isWeekend(date) {
|
|
83
|
+
const dayOfWeek = date.getDay();
|
|
84
|
+
return dayOfWeek === 0 || dayOfWeek === 6; // Sunday or Saturday
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if a date is a weekday (Monday through Friday)
|
|
88
|
+
* @param date - date to check
|
|
89
|
+
*/
|
|
90
|
+
export function isWeekday(date) {
|
|
91
|
+
return !isWeekend(date);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if a time string is valid (HH:MM or HH:MM:SS format)
|
|
95
|
+
* @param time - time string to validate
|
|
96
|
+
*/
|
|
97
|
+
export function isValidTimeString(time) {
|
|
98
|
+
const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/;
|
|
99
|
+
return timeRegex.test(time);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Check if a date string is valid ISO 8601 format
|
|
103
|
+
* @param dateString - date string to validate
|
|
104
|
+
*/
|
|
105
|
+
export function isValidISOString(dateString) {
|
|
106
|
+
const isoRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/;
|
|
107
|
+
return isoRegex.test(dateString) && isValidDate(dateString);
|
|
108
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Working hours utilities */
|
|
2
|
+
export interface WorkingHoursConfig {
|
|
3
|
+
workingDays: number[];
|
|
4
|
+
hours: {
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
};
|
|
8
|
+
breaks?: {
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
}[];
|
|
12
|
+
timezone?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const DEFAULT_WORKING_HOURS: WorkingHoursConfig;
|
|
15
|
+
/** Check if a date is a configured working day */
|
|
16
|
+
export declare function isWorkingDay(date: Date, config?: WorkingHoursConfig): boolean;
|
|
17
|
+
/** Check if inside working hours (excluding breaks) */
|
|
18
|
+
export declare function isWorkingTime(date: Date, config?: WorkingHoursConfig): boolean;
|
|
19
|
+
/** Move date forward to next working minute */
|
|
20
|
+
export declare function nextWorkingTime(date: Date, config?: WorkingHoursConfig): Date;
|
|
21
|
+
/** Compute working time (ms) between two dates */
|
|
22
|
+
export declare function workingTimeBetween(start: Date, end: Date, config?: WorkingHoursConfig): number;
|
|
23
|
+
/** Advance by working hours amount (simple iterative approach) */
|
|
24
|
+
export declare function addWorkingHours(start: Date, hours: number, config?: WorkingHoursConfig): Date;
|
|
25
|
+
//# sourceMappingURL=workingHours.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workingHours.d.ts","sourceRoot":"","sources":["../../src/workingHours.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,qBAAqB,EAAE,kBAInC,CAAC;AAEF,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,kBAA0C,GAAG,OAAO,CAEpG;AAOD,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,kBAA0C,GAAG,OAAO,CAUrG;AAED,+CAA+C;AAC/C,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,kBAA0C,GAAG,IAAI,CAMpG;AAYD,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAE,kBAA0C,GAAG,MAAM,CA+BrH;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,kBAA0C,GAAG,IAAI,CAcpH"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/** Working hours utilities */
|
|
2
|
+
export const DEFAULT_WORKING_HOURS = {
|
|
3
|
+
workingDays: [1, 2, 3, 4, 5],
|
|
4
|
+
hours: { start: 9, end: 17 },
|
|
5
|
+
breaks: [{ start: 12, end: 13 }]
|
|
6
|
+
};
|
|
7
|
+
/** Check if a date is a configured working day */
|
|
8
|
+
export function isWorkingDay(date, config = DEFAULT_WORKING_HOURS) {
|
|
9
|
+
return config.workingDays.includes(date.getDay());
|
|
10
|
+
}
|
|
11
|
+
/** Convert date to fractional hour */
|
|
12
|
+
function toHourFraction(date) {
|
|
13
|
+
return date.getHours() + date.getMinutes() / 60 + date.getSeconds() / 3600;
|
|
14
|
+
}
|
|
15
|
+
/** Check if inside working hours (excluding breaks) */
|
|
16
|
+
export function isWorkingTime(date, config = DEFAULT_WORKING_HOURS) {
|
|
17
|
+
if (!isWorkingDay(date, config))
|
|
18
|
+
return false;
|
|
19
|
+
const h = toHourFraction(date);
|
|
20
|
+
if (h < config.hours.start || h >= config.hours.end)
|
|
21
|
+
return false;
|
|
22
|
+
if (config.breaks) {
|
|
23
|
+
for (const b of config.breaks) {
|
|
24
|
+
if (h >= b.start && h < b.end)
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
/** Move date forward to next working minute */
|
|
31
|
+
export function nextWorkingTime(date, config = DEFAULT_WORKING_HOURS) {
|
|
32
|
+
const d = new Date(date);
|
|
33
|
+
while (!isWorkingTime(d, config)) {
|
|
34
|
+
d.setMinutes(d.getMinutes() + 1);
|
|
35
|
+
}
|
|
36
|
+
return d;
|
|
37
|
+
}
|
|
38
|
+
/** Clamp a date into working window of its day */
|
|
39
|
+
function clampToWorkingWindow(date, config) {
|
|
40
|
+
if (!isWorkingDay(date, config))
|
|
41
|
+
return null;
|
|
42
|
+
const start = new Date(date);
|
|
43
|
+
start.setHours(config.hours.start, 0, 0, 0);
|
|
44
|
+
const end = new Date(date);
|
|
45
|
+
end.setHours(config.hours.end, 0, 0, 0);
|
|
46
|
+
if (date < start)
|
|
47
|
+
return start;
|
|
48
|
+
if (date > end)
|
|
49
|
+
return null;
|
|
50
|
+
return date;
|
|
51
|
+
}
|
|
52
|
+
/** Compute working time (ms) between two dates */
|
|
53
|
+
export function workingTimeBetween(start, end, config = DEFAULT_WORKING_HOURS) {
|
|
54
|
+
if (end <= start)
|
|
55
|
+
return 0;
|
|
56
|
+
let total = 0;
|
|
57
|
+
const cursor = new Date(start);
|
|
58
|
+
while (cursor < end) {
|
|
59
|
+
if (isWorkingDay(cursor, config)) {
|
|
60
|
+
const windowStart = new Date(cursor);
|
|
61
|
+
windowStart.setHours(config.hours.start, 0, 0, 0);
|
|
62
|
+
const windowEnd = new Date(cursor);
|
|
63
|
+
windowEnd.setHours(config.hours.end, 0, 0, 0);
|
|
64
|
+
const rangeStart = cursor > windowStart ? cursor : windowStart;
|
|
65
|
+
const rangeEnd = end < windowEnd ? end : windowEnd;
|
|
66
|
+
if (rangeStart < rangeEnd) {
|
|
67
|
+
let segment = (rangeEnd.getTime() - rangeStart.getTime()) / 1000 / 60 / 60; // hours
|
|
68
|
+
// subtract breaks
|
|
69
|
+
if (config.breaks) {
|
|
70
|
+
for (const b of config.breaks) {
|
|
71
|
+
const bStart = new Date(rangeStart);
|
|
72
|
+
bStart.setHours(Math.floor(b.start), (b.start % 1) * 60, 0, 0);
|
|
73
|
+
const bEnd = new Date(rangeStart);
|
|
74
|
+
bEnd.setHours(Math.floor(b.end), (b.end % 1) * 60, 0, 0);
|
|
75
|
+
const overlapStart = bStart > rangeStart ? bStart : rangeStart;
|
|
76
|
+
const overlapEnd = bEnd < rangeEnd ? bEnd : rangeEnd;
|
|
77
|
+
if (overlapStart < overlapEnd) {
|
|
78
|
+
segment -= (overlapEnd.getTime() - overlapStart.getTime()) / 1000 / 60 / 60;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
total += segment;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// advance to next day start
|
|
86
|
+
cursor.setHours(24, 0, 0, 0);
|
|
87
|
+
}
|
|
88
|
+
return total * 60 * 60 * 1000; // ms
|
|
89
|
+
}
|
|
90
|
+
/** Advance by working hours amount (simple iterative approach) */
|
|
91
|
+
export function addWorkingHours(start, hours, config = DEFAULT_WORKING_HOURS) {
|
|
92
|
+
if (hours <= 0)
|
|
93
|
+
return new Date(start);
|
|
94
|
+
let remaining = hours * 60; // minutes
|
|
95
|
+
let cursor = new Date(start);
|
|
96
|
+
cursor = nextWorkingTime(cursor, config);
|
|
97
|
+
while (remaining > 0) {
|
|
98
|
+
if (isWorkingTime(cursor, config)) {
|
|
99
|
+
cursor.setMinutes(cursor.getMinutes() + 1);
|
|
100
|
+
remaining -= 1;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
cursor = nextWorkingTime(cursor, config);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return cursor;
|
|
107
|
+
}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { FormatOptions } from './constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert milliseconds to a human-readable duration.
|
|
4
|
+
* @param ms - milliseconds
|
|
5
|
+
* @param options - formatting options
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatDuration(ms: number, options?: FormatOptions): string;
|
|
8
|
+
/**
|
|
9
|
+
* Return a human-readable "time ago" string.
|
|
10
|
+
* @param date - past or future date
|
|
11
|
+
* @param options - formatting options
|
|
12
|
+
*/
|
|
13
|
+
export declare function timeAgo(date: Date, options?: FormatOptions): string;
|
|
14
|
+
/**
|
|
15
|
+
* Format a date to a human-readable time string
|
|
16
|
+
* @param date - date to format
|
|
17
|
+
* @param format - format type
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatTime(date: Date, format?: '12h' | '24h' | 'iso'): string;
|
|
20
|
+
/**
|
|
21
|
+
* Parse a duration string like "1h 30m" into milliseconds
|
|
22
|
+
* @param duration - duration string (e.g., "1h 30m", "2d", "45s")
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseDuration(duration: string): number;
|
|
25
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,aAAa,EACd,MAAM,gBAAgB,CAAC;AAExB;;;;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"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
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';
|
|
2
|
+
/**
|
|
3
|
+
* Convert milliseconds to a human-readable duration.
|
|
4
|
+
* @param ms - milliseconds
|
|
5
|
+
* @param options - formatting options
|
|
6
|
+
*/
|
|
7
|
+
export function formatDuration(ms, options = {}) {
|
|
8
|
+
const { includeMs = false, short = false, maxUnits = 2, round = false } = options;
|
|
9
|
+
if (ms < 0)
|
|
10
|
+
return '0' + (short ? 's' : ' seconds');
|
|
11
|
+
const mathFn = round ? Math.round : Math.floor;
|
|
12
|
+
const parts = [];
|
|
13
|
+
let remaining = ms;
|
|
14
|
+
// Years
|
|
15
|
+
if (remaining >= MILLISECONDS_PER_YEAR) {
|
|
16
|
+
const years = mathFn(remaining / MILLISECONDS_PER_YEAR);
|
|
17
|
+
parts.push(years + (short ? 'y' : ` year${years !== 1 ? 's' : ''}`));
|
|
18
|
+
remaining %= MILLISECONDS_PER_YEAR;
|
|
19
|
+
}
|
|
20
|
+
// Months
|
|
21
|
+
if (remaining >= MILLISECONDS_PER_MONTH && parts.length < maxUnits) {
|
|
22
|
+
const months = mathFn(remaining / MILLISECONDS_PER_MONTH);
|
|
23
|
+
parts.push(months + (short ? 'mo' : ` month${months !== 1 ? 's' : ''}`));
|
|
24
|
+
remaining %= MILLISECONDS_PER_MONTH;
|
|
25
|
+
}
|
|
26
|
+
// Weeks
|
|
27
|
+
if (remaining >= MILLISECONDS_PER_WEEK && parts.length < maxUnits) {
|
|
28
|
+
const weeks = mathFn(remaining / MILLISECONDS_PER_WEEK);
|
|
29
|
+
parts.push(weeks + (short ? 'w' : ` week${weeks !== 1 ? 's' : ''}`));
|
|
30
|
+
remaining %= MILLISECONDS_PER_WEEK;
|
|
31
|
+
}
|
|
32
|
+
// Days
|
|
33
|
+
if (remaining >= MILLISECONDS_PER_DAY && parts.length < maxUnits) {
|
|
34
|
+
const days = mathFn(remaining / MILLISECONDS_PER_DAY);
|
|
35
|
+
parts.push(days + (short ? 'd' : ` day${days !== 1 ? 's' : ''}`));
|
|
36
|
+
remaining %= MILLISECONDS_PER_DAY;
|
|
37
|
+
}
|
|
38
|
+
// Hours
|
|
39
|
+
if (remaining >= MILLISECONDS_PER_HOUR && parts.length < maxUnits) {
|
|
40
|
+
const hours = mathFn(remaining / MILLISECONDS_PER_HOUR);
|
|
41
|
+
parts.push(hours + (short ? 'h' : ` hour${hours !== 1 ? 's' : ''}`));
|
|
42
|
+
remaining %= MILLISECONDS_PER_HOUR;
|
|
43
|
+
}
|
|
44
|
+
// Minutes
|
|
45
|
+
if (remaining >= MILLISECONDS_PER_MINUTE && parts.length < maxUnits) {
|
|
46
|
+
const minutes = mathFn(remaining / MILLISECONDS_PER_MINUTE);
|
|
47
|
+
parts.push(minutes + (short ? 'm' : ` minute${minutes !== 1 ? 's' : ''}`));
|
|
48
|
+
remaining %= MILLISECONDS_PER_MINUTE;
|
|
49
|
+
}
|
|
50
|
+
// Seconds
|
|
51
|
+
if (remaining >= MILLISECONDS_PER_SECOND && parts.length < maxUnits) {
|
|
52
|
+
const seconds = mathFn(remaining / MILLISECONDS_PER_SECOND);
|
|
53
|
+
parts.push(seconds + (short ? 's' : ` second${seconds !== 1 ? 's' : ''}`));
|
|
54
|
+
remaining %= MILLISECONDS_PER_SECOND;
|
|
55
|
+
}
|
|
56
|
+
// Milliseconds
|
|
57
|
+
if ((remaining > 0 || parts.length === 0) && includeMs && parts.length < maxUnits) {
|
|
58
|
+
const milliseconds = mathFn(remaining);
|
|
59
|
+
parts.push(milliseconds + (short ? 'ms' : ` millisecond${milliseconds !== 1 ? 's' : ''}`));
|
|
60
|
+
}
|
|
61
|
+
if (parts.length === 0) {
|
|
62
|
+
return '0' + (short ? 's' : ' seconds');
|
|
63
|
+
}
|
|
64
|
+
return short ? parts.join(' ') : parts.join(', ');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Return a human-readable "time ago" string.
|
|
68
|
+
* @param date - past or future date
|
|
69
|
+
* @param options - formatting options
|
|
70
|
+
*/
|
|
71
|
+
export function timeAgo(date, options = {}) {
|
|
72
|
+
const now = new Date();
|
|
73
|
+
const diffMs = now.getTime() - date.getTime();
|
|
74
|
+
const { short = false } = options;
|
|
75
|
+
const isFuture = diffMs < 0;
|
|
76
|
+
const absDiffMs = Math.abs(diffMs);
|
|
77
|
+
if (absDiffMs < MILLISECONDS_PER_MINUTE) {
|
|
78
|
+
const seconds = Math.floor(absDiffMs / MILLISECONDS_PER_SECOND);
|
|
79
|
+
const unit = short ? 's' : ` second${seconds !== 1 ? 's' : ''}`;
|
|
80
|
+
return isFuture ? `in ${seconds}${unit}` : `${seconds}${unit} ago`;
|
|
81
|
+
}
|
|
82
|
+
if (absDiffMs < MILLISECONDS_PER_HOUR) {
|
|
83
|
+
const minutes = Math.floor(absDiffMs / MILLISECONDS_PER_MINUTE);
|
|
84
|
+
const unit = short ? 'm' : ` minute${minutes !== 1 ? 's' : ''}`;
|
|
85
|
+
return isFuture ? `in ${minutes}${unit}` : `${minutes}${unit} ago`;
|
|
86
|
+
}
|
|
87
|
+
if (absDiffMs < MILLISECONDS_PER_DAY) {
|
|
88
|
+
const hours = Math.floor(absDiffMs / MILLISECONDS_PER_HOUR);
|
|
89
|
+
const unit = short ? 'h' : ` hour${hours !== 1 ? 's' : ''}`;
|
|
90
|
+
return isFuture ? `in ${hours}${unit}` : `${hours}${unit} ago`;
|
|
91
|
+
}
|
|
92
|
+
if (absDiffMs < MILLISECONDS_PER_WEEK) {
|
|
93
|
+
const days = Math.floor(absDiffMs / MILLISECONDS_PER_DAY);
|
|
94
|
+
const unit = short ? 'd' : ` day${days !== 1 ? 's' : ''}`;
|
|
95
|
+
return isFuture ? `in ${days}${unit}` : `${days}${unit} ago`;
|
|
96
|
+
}
|
|
97
|
+
if (absDiffMs < MILLISECONDS_PER_MONTH) {
|
|
98
|
+
const weeks = Math.floor(absDiffMs / MILLISECONDS_PER_WEEK);
|
|
99
|
+
const unit = short ? 'w' : ` week${weeks !== 1 ? 's' : ''}`;
|
|
100
|
+
return isFuture ? `in ${weeks}${unit}` : `${weeks}${unit} ago`;
|
|
101
|
+
}
|
|
102
|
+
if (absDiffMs < MILLISECONDS_PER_YEAR) {
|
|
103
|
+
const months = Math.floor(absDiffMs / MILLISECONDS_PER_MONTH);
|
|
104
|
+
const unit = short ? 'mo' : ` month${months !== 1 ? 's' : ''}`;
|
|
105
|
+
return isFuture ? `in ${months}${unit}` : `${months}${unit} ago`;
|
|
106
|
+
}
|
|
107
|
+
const years = Math.floor(absDiffMs / MILLISECONDS_PER_YEAR);
|
|
108
|
+
const unit = short ? 'y' : ` year${years !== 1 ? 's' : ''}`;
|
|
109
|
+
return isFuture ? `in ${years}${unit}` : `${years}${unit} ago`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Format a date to a human-readable time string
|
|
113
|
+
* @param date - date to format
|
|
114
|
+
* @param format - format type
|
|
115
|
+
*/
|
|
116
|
+
export function formatTime(date, format = '24h') {
|
|
117
|
+
switch (format) {
|
|
118
|
+
case '12h':
|
|
119
|
+
return date.toLocaleTimeString('en-US', {
|
|
120
|
+
hour: 'numeric',
|
|
121
|
+
minute: '2-digit',
|
|
122
|
+
hour12: true
|
|
123
|
+
});
|
|
124
|
+
case 'iso':
|
|
125
|
+
return date.toISOString();
|
|
126
|
+
case '24h':
|
|
127
|
+
default:
|
|
128
|
+
return date.toTimeString().split(' ')[0].slice(0, 5); // HH:MM
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Parse a duration string like "1h 30m" into milliseconds
|
|
133
|
+
* @param duration - duration string (e.g., "1h 30m", "2d", "45s")
|
|
134
|
+
*/
|
|
135
|
+
export function parseDuration(duration) {
|
|
136
|
+
const regex = /(\d+(?:\.\d+)?)\s*([a-zA-Z]+)/g;
|
|
137
|
+
let totalMs = 0;
|
|
138
|
+
let match;
|
|
139
|
+
while ((match = regex.exec(duration)) !== null) {
|
|
140
|
+
const value = parseFloat(match[1]);
|
|
141
|
+
const unit = match[2].toLowerCase();
|
|
142
|
+
switch (unit) {
|
|
143
|
+
case 'ms':
|
|
144
|
+
case 'millisecond':
|
|
145
|
+
case 'milliseconds':
|
|
146
|
+
totalMs += value;
|
|
147
|
+
break;
|
|
148
|
+
case 's':
|
|
149
|
+
case 'sec':
|
|
150
|
+
case 'second':
|
|
151
|
+
case 'seconds':
|
|
152
|
+
totalMs += value * MILLISECONDS_PER_SECOND;
|
|
153
|
+
break;
|
|
154
|
+
case 'm':
|
|
155
|
+
case 'min':
|
|
156
|
+
case 'minute':
|
|
157
|
+
case 'minutes':
|
|
158
|
+
totalMs += value * MILLISECONDS_PER_MINUTE;
|
|
159
|
+
break;
|
|
160
|
+
case 'h':
|
|
161
|
+
case 'hr':
|
|
162
|
+
case 'hour':
|
|
163
|
+
case 'hours':
|
|
164
|
+
totalMs += value * MILLISECONDS_PER_HOUR;
|
|
165
|
+
break;
|
|
166
|
+
case 'd':
|
|
167
|
+
case 'day':
|
|
168
|
+
case 'days':
|
|
169
|
+
totalMs += value * MILLISECONDS_PER_DAY;
|
|
170
|
+
break;
|
|
171
|
+
case 'w':
|
|
172
|
+
case 'week':
|
|
173
|
+
case 'weeks':
|
|
174
|
+
totalMs += value * MILLISECONDS_PER_WEEK;
|
|
175
|
+
break;
|
|
176
|
+
case 'mo':
|
|
177
|
+
case 'month':
|
|
178
|
+
case 'months':
|
|
179
|
+
totalMs += value * MILLISECONDS_PER_MONTH;
|
|
180
|
+
break;
|
|
181
|
+
case 'y':
|
|
182
|
+
case 'year':
|
|
183
|
+
case 'years':
|
|
184
|
+
totalMs += value * MILLISECONDS_PER_YEAR;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return totalMs;
|
|
189
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Main entry point for ts-time-utils library
|
|
3
|
+
* Re-exports all functions from individual modules for convenience
|
|
4
|
+
*/
|
|
5
|
+
export { formatDuration, timeAgo, formatTime, parseDuration } from './format.js';
|
|
6
|
+
export { differenceInUnits, addTime, subtractTime, startOf, endOf, isBetween, businessDaysBetween } from './calculate.js';
|
|
7
|
+
export { isValidDate, isLeapYear, isPast, isFuture, isToday, isYesterday, isTomorrow, isSameDay, isWeekend, isWeekday, isValidTimeString, isValidISOString } from './validate.js';
|
|
8
|
+
export { calculateAge, getAgeInUnits, getLifeStage, getNextBirthday, getDaysUntilBirthday, isBirthday, type AgeResult } from './age.js';
|
|
9
|
+
export { getWeekNumber, getWeekOfMonth, getQuarter, getDayOfYear, getWeeksInYear, getDaysInMonth, getDaysInYear, getEaster, getMonthsInYear, getDaysInMonthArray, getWeekdaysInMonth, getFirstDayOfMonth, getLastDayOfMonth, getFirstDayOfYear, getLastDayOfYear } from './calendar.js';
|
|
10
|
+
export { parseDate, parseRelativeDate, parseTimeAgo, parseCustomFormat, parseManyFormats } from './parse.js';
|
|
11
|
+
export { sleep, timeout, debounce, throttle, retry, createStopwatch, measureTime, measureAsync, benchmark, Stopwatch, type BenchmarkResult } from './performance.js';
|
|
12
|
+
export { createInterval, isValidInterval, intervalDuration, intervalContains, intervalsOverlap, intervalIntersection, mergeIntervals, subtractInterval, splitIntervalByDay, totalIntervalCoverage, normalizeIntervals, type Interval } from './interval.js';
|
|
13
|
+
export { getTimezoneOffset, formatInTimeZone, getZonedTime, convertDateToZone, isValidTimeZone, COMMON_TIMEZONES, getLocalOffset, compareZoneOffsets, reinterpretAsZone, type ZonedTime } from './timezone.js';
|
|
14
|
+
export { DEFAULT_WORKING_HOURS, isWorkingDay, isWorkingTime, nextWorkingTime, workingTimeBetween, addWorkingHours, type WorkingHoursConfig } from './workingHours.js';
|
|
15
|
+
export { today, yesterday, tomorrow, lastNDays, nextNDays, thisWeek, lastWeek, nextWeek, thisMonth, lastMonth, nextMonth, thisYear, lastYear, nextYear, rollingWindowDays, quarterRange, lastQuarter, nextQuarter, RANGE_PRESETS, type DateRange } from './rangePresets.js';
|
|
16
|
+
export { MILLISECONDS_PER_SECOND, MILLISECONDS_PER_MINUTE, MILLISECONDS_PER_HOUR, MILLISECONDS_PER_DAY, MILLISECONDS_PER_WEEK, MILLISECONDS_PER_MONTH, MILLISECONDS_PER_YEAR, SECONDS_PER_MINUTE, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, type TimeUnit, type FormatOptions } from './constants.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,cAAc,EACd,OAAO,EACP,UAAU,EACV,aAAa,EACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,iBAAiB,EACjB,OAAO,EACP,YAAY,EACZ,OAAO,EACP,KAAK,EACL,SAAS,EACT,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,WAAW,EACX,UAAU,EACV,MAAM,EACN,QAAQ,EACR,OAAO,EACP,WAAW,EACX,UAAU,EACV,SAAS,EACT,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,aAAa,EACb,cAAc,EACd,UAAU,EACV,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,EACb,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,KAAK,EACL,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,QAAQ,EACd,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,KAAK,EACL,SAAS,EACT,QAAQ,EACR,SAAS,EACT,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,WAAW,EACX,aAAa,EACb,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Main entry point for ts-time-utils library
|
|
3
|
+
* Re-exports all functions from individual modules for convenience
|
|
4
|
+
*/
|
|
5
|
+
// Format utilities
|
|
6
|
+
export { formatDuration, timeAgo, formatTime, parseDuration } from './format.js';
|
|
7
|
+
// Calculation utilities
|
|
8
|
+
export { differenceInUnits, addTime, subtractTime, startOf, endOf, isBetween, businessDaysBetween } from './calculate.js';
|
|
9
|
+
// Validation utilities
|
|
10
|
+
export { isValidDate, isLeapYear, isPast, isFuture, isToday, isYesterday, isTomorrow, isSameDay, isWeekend, isWeekday, isValidTimeString, isValidISOString } from './validate.js';
|
|
11
|
+
// Age utilities
|
|
12
|
+
export { calculateAge, getAgeInUnits, getLifeStage, getNextBirthday, getDaysUntilBirthday, isBirthday } from './age.js';
|
|
13
|
+
// Calendar utilities
|
|
14
|
+
export { getWeekNumber, getWeekOfMonth, getQuarter, getDayOfYear, getWeeksInYear, getDaysInMonth, getDaysInYear, getEaster, getMonthsInYear, getDaysInMonthArray, getWeekdaysInMonth, getFirstDayOfMonth, getLastDayOfMonth, getFirstDayOfYear, getLastDayOfYear } from './calendar.js';
|
|
15
|
+
// Parse utilities
|
|
16
|
+
export { parseDate, parseRelativeDate, parseTimeAgo, parseCustomFormat, parseManyFormats } from './parse.js';
|
|
17
|
+
// Performance utilities
|
|
18
|
+
export { sleep, timeout, debounce, throttle, retry, createStopwatch, measureTime, measureAsync, benchmark, Stopwatch } from './performance.js';
|
|
19
|
+
// Interval utilities
|
|
20
|
+
export { createInterval, isValidInterval, intervalDuration, intervalContains, intervalsOverlap, intervalIntersection, mergeIntervals, subtractInterval, splitIntervalByDay, totalIntervalCoverage, normalizeIntervals } from './interval.js';
|
|
21
|
+
// Timezone utilities
|
|
22
|
+
export { getTimezoneOffset, formatInTimeZone, getZonedTime, convertDateToZone, isValidTimeZone, COMMON_TIMEZONES, getLocalOffset, compareZoneOffsets, reinterpretAsZone } from './timezone.js';
|
|
23
|
+
// Working hours utilities
|
|
24
|
+
export { DEFAULT_WORKING_HOURS, isWorkingDay, isWorkingTime, nextWorkingTime, workingTimeBetween, addWorkingHours } from './workingHours.js';
|
|
25
|
+
// Range preset utilities
|
|
26
|
+
export { today, yesterday, tomorrow, lastNDays, nextNDays, thisWeek, lastWeek, nextWeek, thisMonth, lastMonth, nextMonth, thisYear, lastYear, nextYear, rollingWindowDays, quarterRange, lastQuarter, nextQuarter, RANGE_PRESETS } from './rangePresets.js';
|
|
27
|
+
// Constants and types
|
|
28
|
+
export { MILLISECONDS_PER_SECOND, MILLISECONDS_PER_MINUTE, MILLISECONDS_PER_HOUR, MILLISECONDS_PER_DAY, MILLISECONDS_PER_WEEK, MILLISECONDS_PER_MONTH, MILLISECONDS_PER_YEAR, SECONDS_PER_MINUTE, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK } from './constants.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interval utilities: operations on time intervals [start, end)
|
|
3
|
+
*/
|
|
4
|
+
export interface Interval {
|
|
5
|
+
start: Date;
|
|
6
|
+
end: Date;
|
|
7
|
+
}
|
|
8
|
+
/** Create an interval ensuring start <= end */
|
|
9
|
+
export declare function createInterval(start: Date | string | number, end: Date | string | number): Interval | null;
|
|
10
|
+
/** Validate an object is a proper interval */
|
|
11
|
+
export declare function isValidInterval(i: any): i is Interval;
|
|
12
|
+
/** Duration of interval in ms */
|
|
13
|
+
export declare function intervalDuration(i: Interval): number;
|
|
14
|
+
/** Whether interval contains date (inclusive start, exclusive end) */
|
|
15
|
+
export declare function intervalContains(i: Interval, date: Date | number): boolean;
|
|
16
|
+
/** Whether two intervals overlap */
|
|
17
|
+
export declare function intervalsOverlap(a: Interval, b: Interval): boolean;
|
|
18
|
+
/** Intersection of two intervals, or null */
|
|
19
|
+
export declare function intervalIntersection(a: Interval, b: Interval): Interval | null;
|
|
20
|
+
/** Merge overlapping or touching intervals into a minimal set */
|
|
21
|
+
export declare function mergeIntervals(intervals: Interval[]): Interval[];
|
|
22
|
+
/** Subtract interval b from a (can split into 0,1,2 intervals) */
|
|
23
|
+
export declare function subtractInterval(a: Interval, b: Interval): Interval[];
|
|
24
|
+
/** Split an interval into day-boundary intervals (UTC based) */
|
|
25
|
+
export declare function splitIntervalByDay(i: Interval): Interval[];
|
|
26
|
+
/** Total covered duration of possibly overlapping intervals */
|
|
27
|
+
export declare function totalIntervalCoverage(intervals: Interval[]): number;
|
|
28
|
+
/** Normalize array: filter invalid and merge */
|
|
29
|
+
export declare function normalizeIntervals(intervals: (Interval | null | undefined)[]): Interval[];
|
|
30
|
+
//# sourceMappingURL=interval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interval.d.ts","sourceRoot":"","sources":["../src/interval.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;CACX;AAED,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CAK1G;AAED,8CAA8C;AAC9C,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,QAAQ,CAErD;AAED,iCAAiC;AACjC,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAEpD;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAG1E;AAED,oCAAoC;AACpC,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAElE;AAED,6CAA6C;AAC7C,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAI9E;AAED,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAgBhE;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAMrE;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAU1D;AAED,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAEnE;AAED,gDAAgD;AAChD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,CAAC,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,QAAQ,EAAE,CAEzF"}
|