ts-time-utils 1.1.0 → 3.0.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 +567 -12
- package/dist/calculate.d.ts +7 -2
- package/dist/calculate.d.ts.map +1 -1
- package/dist/calculate.js +13 -3
- package/dist/calendar.d.ts +103 -0
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +224 -0
- package/dist/chain.d.ts +269 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +422 -0
- package/dist/compare.d.ts +217 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/compare.js +417 -0
- package/dist/cron.d.ts +82 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +294 -0
- package/dist/esm/calculate.d.ts +7 -2
- package/dist/esm/calculate.d.ts.map +1 -1
- package/dist/esm/calculate.js +13 -3
- package/dist/esm/calendar.d.ts +103 -0
- package/dist/esm/calendar.d.ts.map +1 -1
- package/dist/esm/calendar.js +224 -0
- package/dist/esm/chain.d.ts +269 -0
- package/dist/esm/chain.d.ts.map +1 -0
- package/dist/esm/chain.js +422 -0
- package/dist/esm/compare.d.ts +217 -0
- package/dist/esm/compare.d.ts.map +1 -0
- package/dist/esm/compare.js +417 -0
- package/dist/esm/cron.d.ts +82 -0
- package/dist/esm/cron.d.ts.map +1 -0
- package/dist/esm/cron.js +294 -0
- package/dist/esm/fiscal.d.ts +195 -0
- package/dist/esm/fiscal.d.ts.map +1 -0
- package/dist/esm/fiscal.js +295 -0
- package/dist/esm/format.d.ts +65 -0
- package/dist/esm/format.d.ts.map +1 -1
- package/dist/esm/format.js +202 -0
- package/dist/esm/holidays.d.ts +62 -0
- package/dist/esm/holidays.d.ts.map +1 -0
- package/dist/esm/holidays.js +793 -0
- package/dist/esm/index.d.ts +18 -6
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +20 -6
- package/dist/esm/iterate.d.ts +212 -0
- package/dist/esm/iterate.d.ts.map +1 -0
- package/dist/esm/iterate.js +409 -0
- package/dist/esm/parse.d.ts +45 -0
- package/dist/esm/parse.d.ts.map +1 -1
- package/dist/esm/parse.js +207 -0
- package/dist/esm/plugins.d.ts +129 -0
- package/dist/esm/plugins.d.ts.map +1 -0
- package/dist/esm/plugins.js +173 -0
- package/dist/esm/timezone.d.ts +52 -0
- package/dist/esm/timezone.d.ts.map +1 -1
- package/dist/esm/timezone.js +171 -0
- package/dist/esm/validate.d.ts +51 -0
- package/dist/esm/validate.d.ts.map +1 -1
- package/dist/esm/validate.js +92 -0
- package/dist/esm/workingHours.d.ts +70 -0
- package/dist/esm/workingHours.d.ts.map +1 -1
- package/dist/esm/workingHours.js +161 -0
- package/dist/fiscal.d.ts +195 -0
- package/dist/fiscal.d.ts.map +1 -0
- package/dist/fiscal.js +295 -0
- package/dist/format.d.ts +65 -0
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +202 -0
- package/dist/holidays.d.ts +62 -0
- package/dist/holidays.d.ts.map +1 -0
- package/dist/holidays.js +793 -0
- package/dist/index.d.ts +18 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -6
- package/dist/iterate.d.ts +212 -0
- package/dist/iterate.d.ts.map +1 -0
- package/dist/iterate.js +409 -0
- package/dist/parse.d.ts +45 -0
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +207 -0
- package/dist/plugins.d.ts +129 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +173 -0
- package/dist/timezone.d.ts +52 -0
- package/dist/timezone.d.ts.map +1 -1
- package/dist/timezone.js +171 -0
- package/dist/validate.d.ts +51 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +92 -0
- package/dist/workingHours.d.ts +70 -0
- package/dist/workingHours.d.ts.map +1 -1
- package/dist/workingHours.js +161 -0
- package/package.json +40 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron expression utilities for scheduling
|
|
3
|
+
*/
|
|
4
|
+
export interface CronParts {
|
|
5
|
+
minute: string;
|
|
6
|
+
hour: string;
|
|
7
|
+
dayOfMonth: string;
|
|
8
|
+
month: string;
|
|
9
|
+
dayOfWeek: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ParsedCronField {
|
|
12
|
+
type: 'all' | 'specific' | 'range' | 'step' | 'list';
|
|
13
|
+
values: number[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse a cron expression into its parts
|
|
17
|
+
* @param expression - cron expression (5 fields: minute hour dayOfMonth month dayOfWeek)
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseCronExpression(expression: string): CronParts | null;
|
|
20
|
+
/**
|
|
21
|
+
* Parse a cron field into its numeric values
|
|
22
|
+
* @param field - cron field string (e.g., "star/5", "1-5", "1,2,3", "*")
|
|
23
|
+
* @param min - minimum valid value
|
|
24
|
+
* @param max - maximum valid value
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseCronField(field: string, min: number, max: number): ParsedCronField | null;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a date matches a cron expression
|
|
29
|
+
* @param date - date to check
|
|
30
|
+
* @param expression - cron expression
|
|
31
|
+
*/
|
|
32
|
+
export declare function matchesCron(date: Date, expression: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get the next date that matches a cron expression
|
|
35
|
+
* @param expression - cron expression
|
|
36
|
+
* @param after - start searching after this date (default: now)
|
|
37
|
+
* @param maxIterations - maximum iterations to prevent infinite loops
|
|
38
|
+
*/
|
|
39
|
+
export declare function getNextCronDate(expression: string, after?: Date, maxIterations?: number): Date | null;
|
|
40
|
+
/**
|
|
41
|
+
* Get the N next dates that match a cron expression
|
|
42
|
+
* @param expression - cron expression
|
|
43
|
+
* @param count - number of dates to get
|
|
44
|
+
* @param after - start searching after this date
|
|
45
|
+
*/
|
|
46
|
+
export declare function getNextCronDates(expression: string, count: number, after?: Date): Date[];
|
|
47
|
+
/**
|
|
48
|
+
* Get the previous date that matched a cron expression
|
|
49
|
+
* @param expression - cron expression
|
|
50
|
+
* @param before - start searching before this date
|
|
51
|
+
* @param maxIterations - maximum iterations to prevent infinite loops
|
|
52
|
+
*/
|
|
53
|
+
export declare function getPreviousCronDate(expression: string, before?: Date, maxIterations?: number): Date | null;
|
|
54
|
+
/**
|
|
55
|
+
* Validate a cron expression
|
|
56
|
+
* @param expression - cron expression to validate
|
|
57
|
+
*/
|
|
58
|
+
export declare function isValidCron(expression: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Convert a cron expression to a human-readable description
|
|
61
|
+
* @param expression - cron expression
|
|
62
|
+
*/
|
|
63
|
+
export declare function describeCron(expression: string): string | null;
|
|
64
|
+
/**
|
|
65
|
+
* Common cron expressions
|
|
66
|
+
*/
|
|
67
|
+
export declare const CRON_PRESETS: {
|
|
68
|
+
readonly everyMinute: "* * * * *";
|
|
69
|
+
readonly everyHour: "0 * * * *";
|
|
70
|
+
readonly everyDay: "0 0 * * *";
|
|
71
|
+
readonly everyDayAt9am: "0 9 * * *";
|
|
72
|
+
readonly everyDayAt6pm: "0 18 * * *";
|
|
73
|
+
readonly everyWeek: "0 0 * * 0";
|
|
74
|
+
readonly everyMonth: "0 0 1 * *";
|
|
75
|
+
readonly everyYear: "0 0 1 1 *";
|
|
76
|
+
readonly weekdays: "0 0 * * 1-5";
|
|
77
|
+
readonly weekends: "0 0 * * 0,6";
|
|
78
|
+
readonly every5Minutes: "*/5 * * * *";
|
|
79
|
+
readonly every15Minutes: "*/15 * * * *";
|
|
80
|
+
readonly every30Minutes: "*/30 * * * *";
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=cron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/cron.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACrD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAcxE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA+D9F;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAqBnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,IAAiB,EACxB,aAAa,GAAE,MAAe,GAC7B,IAAI,GAAG,IAAI,CAiCb;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,IAAiB,GACvB,IAAI,EAAE,CAYR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,IAAiB,EACzB,aAAa,GAAE,MAAe,GAC7B,IAAI,GAAG,IAAI,CAiCb;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAWvD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwE9D;AAED;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAcf,CAAC"}
|
package/dist/esm/cron.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron expression utilities for scheduling
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Parse a cron expression into its parts
|
|
6
|
+
* @param expression - cron expression (5 fields: minute hour dayOfMonth month dayOfWeek)
|
|
7
|
+
*/
|
|
8
|
+
export function parseCronExpression(expression) {
|
|
9
|
+
const parts = expression.trim().split(/\s+/);
|
|
10
|
+
if (parts.length !== 5) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
minute: parts[0],
|
|
15
|
+
hour: parts[1],
|
|
16
|
+
dayOfMonth: parts[2],
|
|
17
|
+
month: parts[3],
|
|
18
|
+
dayOfWeek: parts[4],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a cron field into its numeric values
|
|
23
|
+
* @param field - cron field string (e.g., "star/5", "1-5", "1,2,3", "*")
|
|
24
|
+
* @param min - minimum valid value
|
|
25
|
+
* @param max - maximum valid value
|
|
26
|
+
*/
|
|
27
|
+
export function parseCronField(field, min, max) {
|
|
28
|
+
const values = [];
|
|
29
|
+
// Handle wildcard
|
|
30
|
+
if (field === '*') {
|
|
31
|
+
for (let i = min; i <= max; i++) {
|
|
32
|
+
values.push(i);
|
|
33
|
+
}
|
|
34
|
+
return { type: 'all', values };
|
|
35
|
+
}
|
|
36
|
+
// Handle step values (*/n or range/n)
|
|
37
|
+
if (field.includes('/')) {
|
|
38
|
+
const [range, stepStr] = field.split('/');
|
|
39
|
+
const step = parseInt(stepStr, 10);
|
|
40
|
+
if (isNaN(step) || step <= 0)
|
|
41
|
+
return null;
|
|
42
|
+
let start = min;
|
|
43
|
+
let end = max;
|
|
44
|
+
if (range !== '*') {
|
|
45
|
+
if (range.includes('-')) {
|
|
46
|
+
const [s, e] = range.split('-').map(Number);
|
|
47
|
+
start = s;
|
|
48
|
+
end = e;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
start = parseInt(range, 10);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (let i = start; i <= end; i += step) {
|
|
55
|
+
values.push(i);
|
|
56
|
+
}
|
|
57
|
+
return { type: 'step', values };
|
|
58
|
+
}
|
|
59
|
+
// Handle range (n-m)
|
|
60
|
+
if (field.includes('-')) {
|
|
61
|
+
const [start, end] = field.split('-').map(Number);
|
|
62
|
+
if (isNaN(start) || isNaN(end) || start > end)
|
|
63
|
+
return null;
|
|
64
|
+
for (let i = start; i <= end; i++) {
|
|
65
|
+
values.push(i);
|
|
66
|
+
}
|
|
67
|
+
return { type: 'range', values };
|
|
68
|
+
}
|
|
69
|
+
// Handle list (n,m,o)
|
|
70
|
+
if (field.includes(',')) {
|
|
71
|
+
const items = field.split(',').map(Number);
|
|
72
|
+
if (items.some(isNaN))
|
|
73
|
+
return null;
|
|
74
|
+
return { type: 'list', values: items.sort((a, b) => a - b) };
|
|
75
|
+
}
|
|
76
|
+
// Handle specific value
|
|
77
|
+
const value = parseInt(field, 10);
|
|
78
|
+
if (isNaN(value) || value < min || value > max)
|
|
79
|
+
return null;
|
|
80
|
+
return { type: 'specific', values: [value] };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if a date matches a cron expression
|
|
84
|
+
* @param date - date to check
|
|
85
|
+
* @param expression - cron expression
|
|
86
|
+
*/
|
|
87
|
+
export function matchesCron(date, expression) {
|
|
88
|
+
const parts = parseCronExpression(expression);
|
|
89
|
+
if (!parts)
|
|
90
|
+
return false;
|
|
91
|
+
const minute = parseCronField(parts.minute, 0, 59);
|
|
92
|
+
const hour = parseCronField(parts.hour, 0, 23);
|
|
93
|
+
const dayOfMonth = parseCronField(parts.dayOfMonth, 1, 31);
|
|
94
|
+
const month = parseCronField(parts.month, 1, 12);
|
|
95
|
+
const dayOfWeek = parseCronField(parts.dayOfWeek, 0, 6);
|
|
96
|
+
if (!minute || !hour || !dayOfMonth || !month || !dayOfWeek) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return (minute.values.includes(date.getMinutes()) &&
|
|
100
|
+
hour.values.includes(date.getHours()) &&
|
|
101
|
+
dayOfMonth.values.includes(date.getDate()) &&
|
|
102
|
+
month.values.includes(date.getMonth() + 1) &&
|
|
103
|
+
dayOfWeek.values.includes(date.getDay()));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the next date that matches a cron expression
|
|
107
|
+
* @param expression - cron expression
|
|
108
|
+
* @param after - start searching after this date (default: now)
|
|
109
|
+
* @param maxIterations - maximum iterations to prevent infinite loops
|
|
110
|
+
*/
|
|
111
|
+
export function getNextCronDate(expression, after = new Date(), maxIterations = 525600 // Max 1 year in minutes
|
|
112
|
+
) {
|
|
113
|
+
const parts = parseCronExpression(expression);
|
|
114
|
+
if (!parts)
|
|
115
|
+
return null;
|
|
116
|
+
const minute = parseCronField(parts.minute, 0, 59);
|
|
117
|
+
const hour = parseCronField(parts.hour, 0, 23);
|
|
118
|
+
const dayOfMonth = parseCronField(parts.dayOfMonth, 1, 31);
|
|
119
|
+
const month = parseCronField(parts.month, 1, 12);
|
|
120
|
+
const dayOfWeek = parseCronField(parts.dayOfWeek, 0, 6);
|
|
121
|
+
if (!minute || !hour || !dayOfMonth || !month || !dayOfWeek) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const candidate = new Date(after);
|
|
125
|
+
candidate.setSeconds(0, 0);
|
|
126
|
+
candidate.setMinutes(candidate.getMinutes() + 1);
|
|
127
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
128
|
+
if (minute.values.includes(candidate.getMinutes()) &&
|
|
129
|
+
hour.values.includes(candidate.getHours()) &&
|
|
130
|
+
dayOfMonth.values.includes(candidate.getDate()) &&
|
|
131
|
+
month.values.includes(candidate.getMonth() + 1) &&
|
|
132
|
+
dayOfWeek.values.includes(candidate.getDay())) {
|
|
133
|
+
return candidate;
|
|
134
|
+
}
|
|
135
|
+
candidate.setMinutes(candidate.getMinutes() + 1);
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get the N next dates that match a cron expression
|
|
141
|
+
* @param expression - cron expression
|
|
142
|
+
* @param count - number of dates to get
|
|
143
|
+
* @param after - start searching after this date
|
|
144
|
+
*/
|
|
145
|
+
export function getNextCronDates(expression, count, after = new Date()) {
|
|
146
|
+
const dates = [];
|
|
147
|
+
let currentAfter = after;
|
|
148
|
+
for (let i = 0; i < count; i++) {
|
|
149
|
+
const next = getNextCronDate(expression, currentAfter);
|
|
150
|
+
if (!next)
|
|
151
|
+
break;
|
|
152
|
+
dates.push(next);
|
|
153
|
+
currentAfter = next;
|
|
154
|
+
}
|
|
155
|
+
return dates;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get the previous date that matched a cron expression
|
|
159
|
+
* @param expression - cron expression
|
|
160
|
+
* @param before - start searching before this date
|
|
161
|
+
* @param maxIterations - maximum iterations to prevent infinite loops
|
|
162
|
+
*/
|
|
163
|
+
export function getPreviousCronDate(expression, before = new Date(), maxIterations = 525600) {
|
|
164
|
+
const parts = parseCronExpression(expression);
|
|
165
|
+
if (!parts)
|
|
166
|
+
return null;
|
|
167
|
+
const minute = parseCronField(parts.minute, 0, 59);
|
|
168
|
+
const hour = parseCronField(parts.hour, 0, 23);
|
|
169
|
+
const dayOfMonth = parseCronField(parts.dayOfMonth, 1, 31);
|
|
170
|
+
const month = parseCronField(parts.month, 1, 12);
|
|
171
|
+
const dayOfWeek = parseCronField(parts.dayOfWeek, 0, 6);
|
|
172
|
+
if (!minute || !hour || !dayOfMonth || !month || !dayOfWeek) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const candidate = new Date(before);
|
|
176
|
+
candidate.setSeconds(0, 0);
|
|
177
|
+
candidate.setMinutes(candidate.getMinutes() - 1);
|
|
178
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
179
|
+
if (minute.values.includes(candidate.getMinutes()) &&
|
|
180
|
+
hour.values.includes(candidate.getHours()) &&
|
|
181
|
+
dayOfMonth.values.includes(candidate.getDate()) &&
|
|
182
|
+
month.values.includes(candidate.getMonth() + 1) &&
|
|
183
|
+
dayOfWeek.values.includes(candidate.getDay())) {
|
|
184
|
+
return candidate;
|
|
185
|
+
}
|
|
186
|
+
candidate.setMinutes(candidate.getMinutes() - 1);
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Validate a cron expression
|
|
192
|
+
* @param expression - cron expression to validate
|
|
193
|
+
*/
|
|
194
|
+
export function isValidCron(expression) {
|
|
195
|
+
const parts = parseCronExpression(expression);
|
|
196
|
+
if (!parts)
|
|
197
|
+
return false;
|
|
198
|
+
const minute = parseCronField(parts.minute, 0, 59);
|
|
199
|
+
const hour = parseCronField(parts.hour, 0, 23);
|
|
200
|
+
const dayOfMonth = parseCronField(parts.dayOfMonth, 1, 31);
|
|
201
|
+
const month = parseCronField(parts.month, 1, 12);
|
|
202
|
+
const dayOfWeek = parseCronField(parts.dayOfWeek, 0, 6);
|
|
203
|
+
return !!(minute && hour && dayOfMonth && month && dayOfWeek);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Convert a cron expression to a human-readable description
|
|
207
|
+
* @param expression - cron expression
|
|
208
|
+
*/
|
|
209
|
+
export function describeCron(expression) {
|
|
210
|
+
const parts = parseCronExpression(expression);
|
|
211
|
+
if (!parts)
|
|
212
|
+
return null;
|
|
213
|
+
const descriptions = [];
|
|
214
|
+
// Handle common patterns
|
|
215
|
+
if (expression === '* * * * *') {
|
|
216
|
+
return 'Every minute';
|
|
217
|
+
}
|
|
218
|
+
if (expression === '0 * * * *') {
|
|
219
|
+
return 'Every hour';
|
|
220
|
+
}
|
|
221
|
+
if (expression === '0 0 * * *') {
|
|
222
|
+
return 'Every day at midnight';
|
|
223
|
+
}
|
|
224
|
+
if (expression === '0 0 * * 0') {
|
|
225
|
+
return 'Every Sunday at midnight';
|
|
226
|
+
}
|
|
227
|
+
if (expression === '0 0 1 * *') {
|
|
228
|
+
return 'First day of every month at midnight';
|
|
229
|
+
}
|
|
230
|
+
// Build description
|
|
231
|
+
const minute = parts.minute;
|
|
232
|
+
const hour = parts.hour;
|
|
233
|
+
if (minute === '0' && hour !== '*') {
|
|
234
|
+
if (hour.includes('/')) {
|
|
235
|
+
const step = hour.split('/')[1];
|
|
236
|
+
descriptions.push(`Every ${step} hours`);
|
|
237
|
+
}
|
|
238
|
+
else if (hour.includes('-')) {
|
|
239
|
+
descriptions.push(`Every hour from ${hour} at minute 0`);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
descriptions.push(`At ${hour}:00`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else if (minute !== '*' && hour === '*') {
|
|
246
|
+
descriptions.push(`At minute ${minute} of every hour`);
|
|
247
|
+
}
|
|
248
|
+
else if (minute.includes('/')) {
|
|
249
|
+
const step = minute.split('/')[1];
|
|
250
|
+
descriptions.push(`Every ${step} minutes`);
|
|
251
|
+
}
|
|
252
|
+
if (parts.dayOfMonth !== '*') {
|
|
253
|
+
descriptions.push(`on day ${parts.dayOfMonth} of the month`);
|
|
254
|
+
}
|
|
255
|
+
if (parts.month !== '*') {
|
|
256
|
+
const monthNames = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
257
|
+
const monthNum = parseInt(parts.month, 10);
|
|
258
|
+
if (!isNaN(monthNum) && monthNum >= 1 && monthNum <= 12) {
|
|
259
|
+
descriptions.push(`in ${monthNames[monthNum]}`);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
descriptions.push(`in month ${parts.month}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (parts.dayOfWeek !== '*') {
|
|
266
|
+
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
267
|
+
const dayNum = parseInt(parts.dayOfWeek, 10);
|
|
268
|
+
if (!isNaN(dayNum) && dayNum >= 0 && dayNum <= 6) {
|
|
269
|
+
descriptions.push(`on ${dayNames[dayNum]}`);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
descriptions.push(`on day of week ${parts.dayOfWeek}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return descriptions.join(' ') || expression;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Common cron expressions
|
|
279
|
+
*/
|
|
280
|
+
export const CRON_PRESETS = {
|
|
281
|
+
everyMinute: '* * * * *',
|
|
282
|
+
everyHour: '0 * * * *',
|
|
283
|
+
everyDay: '0 0 * * *',
|
|
284
|
+
everyDayAt9am: '0 9 * * *',
|
|
285
|
+
everyDayAt6pm: '0 18 * * *',
|
|
286
|
+
everyWeek: '0 0 * * 0',
|
|
287
|
+
everyMonth: '0 0 1 * *',
|
|
288
|
+
everyYear: '0 0 1 1 *',
|
|
289
|
+
weekdays: '0 0 * * 1-5',
|
|
290
|
+
weekends: '0 0 * * 0,6',
|
|
291
|
+
every5Minutes: '*/5 * * * *',
|
|
292
|
+
every15Minutes: '*/15 * * * *',
|
|
293
|
+
every30Minutes: '*/30 * * * *',
|
|
294
|
+
};
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fiscal year and accounting period utilities
|
|
3
|
+
* Supports configurable fiscal year start months for business calculations
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Fiscal year configuration
|
|
7
|
+
*/
|
|
8
|
+
export interface FiscalConfig {
|
|
9
|
+
/** Month when fiscal year starts (1-12, default: 1 for January) */
|
|
10
|
+
startMonth: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get the fiscal year for a given date
|
|
14
|
+
* @param date - The date to check
|
|
15
|
+
* @param config - Fiscal year configuration
|
|
16
|
+
* @returns The fiscal year number
|
|
17
|
+
* @example
|
|
18
|
+
* // Calendar year (Jan start)
|
|
19
|
+
* getFiscalYear(new Date('2024-03-15')) // 2024
|
|
20
|
+
*
|
|
21
|
+
* // April fiscal year (UK/India style)
|
|
22
|
+
* getFiscalYear(new Date('2024-03-15'), { startMonth: 4 }) // 2023
|
|
23
|
+
* getFiscalYear(new Date('2024-04-15'), { startMonth: 4 }) // 2024
|
|
24
|
+
*
|
|
25
|
+
* // July fiscal year (Australia style)
|
|
26
|
+
* getFiscalYear(new Date('2024-06-15'), { startMonth: 7 }) // 2023
|
|
27
|
+
* getFiscalYear(new Date('2024-07-15'), { startMonth: 7 }) // 2024
|
|
28
|
+
*/
|
|
29
|
+
export declare function getFiscalYear(date: Date, config?: Partial<FiscalConfig>): number;
|
|
30
|
+
/**
|
|
31
|
+
* Get the fiscal quarter for a given date (1-4)
|
|
32
|
+
* @param date - The date to check
|
|
33
|
+
* @param config - Fiscal year configuration
|
|
34
|
+
* @returns The fiscal quarter (1-4)
|
|
35
|
+
* @example
|
|
36
|
+
* // Calendar year quarters
|
|
37
|
+
* getFiscalQuarter(new Date('2024-01-15')) // 1
|
|
38
|
+
* getFiscalQuarter(new Date('2024-04-15')) // 2
|
|
39
|
+
*
|
|
40
|
+
* // April fiscal year
|
|
41
|
+
* getFiscalQuarter(new Date('2024-04-15'), { startMonth: 4 }) // 1
|
|
42
|
+
* getFiscalQuarter(new Date('2024-07-15'), { startMonth: 4 }) // 2
|
|
43
|
+
*/
|
|
44
|
+
export declare function getFiscalQuarter(date: Date, config?: Partial<FiscalConfig>): number;
|
|
45
|
+
/**
|
|
46
|
+
* Get the start date of a fiscal year
|
|
47
|
+
* @param fiscalYear - The fiscal year
|
|
48
|
+
* @param config - Fiscal year configuration
|
|
49
|
+
* @returns Start date of the fiscal year
|
|
50
|
+
* @example
|
|
51
|
+
* getFiscalYearStart(2024) // 2024-01-01
|
|
52
|
+
* getFiscalYearStart(2024, { startMonth: 4 }) // 2024-04-01 (FY2024 starts Apr 2024)
|
|
53
|
+
* getFiscalYearStart(2024, { startMonth: 7 }) // 2024-07-01 (FY2024 starts Jul 2024)
|
|
54
|
+
*/
|
|
55
|
+
export declare function getFiscalYearStart(fiscalYear: number, config?: Partial<FiscalConfig>): Date;
|
|
56
|
+
/**
|
|
57
|
+
* Get the end date of a fiscal year
|
|
58
|
+
* @param fiscalYear - The fiscal year
|
|
59
|
+
* @param config - Fiscal year configuration
|
|
60
|
+
* @returns End date of the fiscal year (last day, 23:59:59.999)
|
|
61
|
+
* @example
|
|
62
|
+
* getFiscalYearEnd(2024) // 2024-12-31
|
|
63
|
+
* getFiscalYearEnd(2024, { startMonth: 4 }) // 2025-03-31 (FY2024 ends Mar 2025)
|
|
64
|
+
* getFiscalYearEnd(2024, { startMonth: 7 }) // 2025-06-30 (FY2024 ends Jun 2025)
|
|
65
|
+
*/
|
|
66
|
+
export declare function getFiscalYearEnd(fiscalYear: number, config?: Partial<FiscalConfig>): Date;
|
|
67
|
+
/**
|
|
68
|
+
* Get the start date of a fiscal quarter
|
|
69
|
+
* @param fiscalYear - The fiscal year
|
|
70
|
+
* @param quarter - The quarter (1-4)
|
|
71
|
+
* @param config - Fiscal year configuration
|
|
72
|
+
* @returns Start date of the fiscal quarter
|
|
73
|
+
* @example
|
|
74
|
+
* getFiscalQuarterStart(2024, 1) // 2024-01-01
|
|
75
|
+
* getFiscalQuarterStart(2024, 2) // 2024-04-01
|
|
76
|
+
* getFiscalQuarterStart(2024, 1, { startMonth: 4 }) // 2023-04-01
|
|
77
|
+
* getFiscalQuarterStart(2024, 2, { startMonth: 4 }) // 2023-07-01
|
|
78
|
+
*/
|
|
79
|
+
export declare function getFiscalQuarterStart(fiscalYear: number, quarter: number, config?: Partial<FiscalConfig>): Date;
|
|
80
|
+
/**
|
|
81
|
+
* Get the end date of a fiscal quarter
|
|
82
|
+
* @param fiscalYear - The fiscal year
|
|
83
|
+
* @param quarter - The quarter (1-4)
|
|
84
|
+
* @param config - Fiscal year configuration
|
|
85
|
+
* @returns End date of the fiscal quarter (last day, 23:59:59.999)
|
|
86
|
+
* @example
|
|
87
|
+
* getFiscalQuarterEnd(2024, 1) // 2024-03-31
|
|
88
|
+
* getFiscalQuarterEnd(2024, 2) // 2024-06-30
|
|
89
|
+
* getFiscalQuarterEnd(2024, 1, { startMonth: 4 }) // 2023-06-30
|
|
90
|
+
*/
|
|
91
|
+
export declare function getFiscalQuarterEnd(fiscalYear: number, quarter: number, config?: Partial<FiscalConfig>): Date;
|
|
92
|
+
/**
|
|
93
|
+
* Check if two dates are in the same fiscal year
|
|
94
|
+
* @param date1 - First date
|
|
95
|
+
* @param date2 - Second date
|
|
96
|
+
* @param config - Fiscal year configuration
|
|
97
|
+
* @returns True if both dates are in the same fiscal year
|
|
98
|
+
*/
|
|
99
|
+
export declare function isSameFiscalYear(date1: Date, date2: Date, config?: Partial<FiscalConfig>): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Check if two dates are in the same fiscal quarter
|
|
102
|
+
* @param date1 - First date
|
|
103
|
+
* @param date2 - Second date
|
|
104
|
+
* @param config - Fiscal year configuration
|
|
105
|
+
* @returns True if both dates are in the same fiscal year and quarter
|
|
106
|
+
*/
|
|
107
|
+
export declare function isSameFiscalQuarter(date1: Date, date2: Date, config?: Partial<FiscalConfig>): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Get the fiscal month (1-12) within the fiscal year
|
|
110
|
+
* @param date - The date to check
|
|
111
|
+
* @param config - Fiscal year configuration
|
|
112
|
+
* @returns The fiscal month (1-12, where 1 is the first month of fiscal year)
|
|
113
|
+
* @example
|
|
114
|
+
* getFiscalMonth(new Date('2024-01-15')) // 1
|
|
115
|
+
* getFiscalMonth(new Date('2024-04-15'), { startMonth: 4 }) // 1
|
|
116
|
+
* getFiscalMonth(new Date('2024-03-15'), { startMonth: 4 }) // 12
|
|
117
|
+
*/
|
|
118
|
+
export declare function getFiscalMonth(date: Date, config?: Partial<FiscalConfig>): number;
|
|
119
|
+
/**
|
|
120
|
+
* Get the number of days remaining in the fiscal year
|
|
121
|
+
* @param date - The date to check
|
|
122
|
+
* @param config - Fiscal year configuration
|
|
123
|
+
* @returns Number of days remaining in the fiscal year
|
|
124
|
+
*/
|
|
125
|
+
export declare function getDaysRemainingInFiscalYear(date: Date, config?: Partial<FiscalConfig>): number;
|
|
126
|
+
/**
|
|
127
|
+
* Get the number of days elapsed in the fiscal year
|
|
128
|
+
* @param date - The date to check
|
|
129
|
+
* @param config - Fiscal year configuration
|
|
130
|
+
* @returns Number of days elapsed in the fiscal year (including the given date)
|
|
131
|
+
*/
|
|
132
|
+
export declare function getDaysElapsedInFiscalYear(date: Date, config?: Partial<FiscalConfig>): number;
|
|
133
|
+
/**
|
|
134
|
+
* Get fiscal year progress as a percentage
|
|
135
|
+
* @param date - The date to check
|
|
136
|
+
* @param config - Fiscal year configuration
|
|
137
|
+
* @returns Percentage of fiscal year completed (0-100)
|
|
138
|
+
*/
|
|
139
|
+
export declare function getFiscalYearProgress(date: Date, config?: Partial<FiscalConfig>): number;
|
|
140
|
+
/**
|
|
141
|
+
* Get the fiscal week number (1-53) within the fiscal year
|
|
142
|
+
* @param date - The date to check
|
|
143
|
+
* @param config - Fiscal year configuration
|
|
144
|
+
* @returns The fiscal week number
|
|
145
|
+
*/
|
|
146
|
+
export declare function getFiscalWeek(date: Date, config?: Partial<FiscalConfig>): number;
|
|
147
|
+
/**
|
|
148
|
+
* Common fiscal year configurations
|
|
149
|
+
*/
|
|
150
|
+
export declare const FISCAL_PRESETS: {
|
|
151
|
+
/** Calendar year (January start) - Default */
|
|
152
|
+
readonly CALENDAR: FiscalConfig;
|
|
153
|
+
/** UK/India government fiscal year (April start) */
|
|
154
|
+
readonly UK_INDIA: FiscalConfig;
|
|
155
|
+
/** Australian fiscal year (July start) */
|
|
156
|
+
readonly AUSTRALIA: FiscalConfig;
|
|
157
|
+
/** US federal government fiscal year (October start) */
|
|
158
|
+
readonly US_FEDERAL: FiscalConfig;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Format fiscal year as string (e.g., "FY2024" or "FY2023/24")
|
|
162
|
+
* @param fiscalYear - The fiscal year
|
|
163
|
+
* @param config - Fiscal year configuration
|
|
164
|
+
* @param format - Format style: 'short' (FY2024) or 'long' (FY2023/24)
|
|
165
|
+
* @returns Formatted fiscal year string
|
|
166
|
+
*/
|
|
167
|
+
export declare function formatFiscalYear(fiscalYear: number, config?: Partial<FiscalConfig>, format?: 'short' | 'long'): string;
|
|
168
|
+
/**
|
|
169
|
+
* Format fiscal quarter as string (e.g., "Q1 FY2024")
|
|
170
|
+
* @param fiscalYear - The fiscal year
|
|
171
|
+
* @param quarter - The quarter (1-4)
|
|
172
|
+
* @param config - Fiscal year configuration
|
|
173
|
+
* @returns Formatted fiscal quarter string
|
|
174
|
+
*/
|
|
175
|
+
export declare function formatFiscalQuarter(fiscalYear: number, quarter: number, config?: Partial<FiscalConfig>): string;
|
|
176
|
+
/**
|
|
177
|
+
* Get fiscal period info for a date
|
|
178
|
+
* @param date - The date to analyze
|
|
179
|
+
* @param config - Fiscal year configuration
|
|
180
|
+
* @returns Object with fiscal period information
|
|
181
|
+
*/
|
|
182
|
+
export declare function getFiscalPeriodInfo(date: Date, config?: Partial<FiscalConfig>): {
|
|
183
|
+
fiscalYear: number;
|
|
184
|
+
fiscalQuarter: number;
|
|
185
|
+
fiscalMonth: number;
|
|
186
|
+
fiscalWeek: number;
|
|
187
|
+
daysElapsed: number;
|
|
188
|
+
daysRemaining: number;
|
|
189
|
+
progress: number;
|
|
190
|
+
quarterStart: Date;
|
|
191
|
+
quarterEnd: Date;
|
|
192
|
+
yearStart: Date;
|
|
193
|
+
yearEnd: Date;
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=fiscal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fiscal.d.ts","sourceRoot":"","sources":["../../src/fiscal.ts"],"names":[],"mappings":"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"}
|