Thank you!
amcdnl opened this issue · comments
I built one of these buts it not as good as yours, thank you for writing this! For fun, I included mine below.
export type IntervalTypes =
| 'minute'
| 'hour'
| 'day'
| 'week'
| 'month'
| 'year';
export type CronObject = {
interval?: IntervalTypes;
daysOfWeek?: number[];
dayOfMonth?: number;
timeOfDay?: any;
month?: number;
minute?: number;
hour?: number;
};
/**
* Given a CRON expression, build a CRON object.
*/
export const buildCronObject = (value: string) => {
const result: CronObject = {};
if (value) {
const [minute, hour, day, month, dayOfTheWeek] = value.split(' ');
const hasHour = hour !== '*';
const hasMinute = minute !== '*';
const hasMonth = month !== '*';
const hasDayOfTheMonth = day !== '*';
const hasDayOfTheWeek = dayOfTheWeek !== '?';
if (hasHour && hasMinute && hasDayOfTheMonth && hasMonth) {
result.interval = 'year';
result.month = parseInt(month);
result.timeOfDay = `${hour}:${minute}`;
result.dayOfMonth = parseInt(day);
} else if (hasHour && hasMinute && hasDayOfTheMonth) {
result.interval = 'month';
result.timeOfDay = `${hour}:${minute}`;
result.dayOfMonth = parseInt(day);
} else if (hasHour && hasMinute && hasDayOfTheWeek) {
result.interval = 'week';
result.timeOfDay = `${hour}:${minute}`;
result.daysOfWeek = dayOfTheWeek.split(',').map(d => parseInt(d));
} else if (hasHour && !hasMinute) {
result.interval = 'hour';
result.hour = parseInt(hour);
} else if (hasHour && hasMinute) {
result.interval = 'day';
result.timeOfDay = `${hour}:${minute}`;
} else if (minute) {
result.interval = 'minute';
const [, minuteInterval] = value.split('/');
result.minute = parseInt(minuteInterval);
}
}
return result;
};
/**
* Given a CRON object, build a expression.
*/
export const buildCronExpression = ({
interval,
dayOfMonth,
daysOfWeek,
hour,
minute,
month,
timeOfDay
}: CronObject) => {
if (interval === 'minute') {
if (minute) {
return `0/${minute} * * * ? *`;
}
} else if (interval === 'hour') {
if (hour) {
return `* ${hour} * * ? *`;
}
} else if (interval === 'day') {
if (timeOfDay) {
const [hourOfDay, minuteOfHour] = timeOfDay.split(':');
return `${minuteOfHour} ${hourOfDay} * * ? *`;
}
} else if (interval === 'week') {
if (timeOfDay && daysOfWeek) {
const [hourOfDay, minuteOfHour] = timeOfDay.split(':');
const dayOfTheWeek = daysOfWeek.map(d => d.toString());
return `${minuteOfHour} ${hourOfDay} * * ${dayOfTheWeek.join(',')} *`;
}
} else if (interval === 'month') {
if (timeOfDay && dayOfMonth) {
const [hourOfDay, minuteOfHour] = timeOfDay.split(':');
return `${minuteOfHour} ${hourOfDay} ${dayOfMonth} * ? *`;
}
} else if (interval === 'year') {
if (timeOfDay && dayOfMonth && month) {
const [hourOfDay, minuteOfHour] = timeOfDay.split(':');
return `${minuteOfHour} ${hourOfDay} ${dayOfMonth} ${month} ? *`;
}
}
};
and
import { buildCronObject, buildCronExpression } from './parser';
describe('CronInput', () => {
it('should build every day at 12:00pm UTC', () => {
const obj = buildCronObject('0 12 * * ? *');
expect(obj.interval).toBe('day');
expect(obj.timeOfDay).toBe('12:0');
const result = buildCronExpression(obj);
expect(result).toBe('0 12 * * ? *');
});
it('should build every day, at 5 and 35 minutes past 2:00pm UTC', () => {
const obj = buildCronObject('5,35 14 * * ? *');
expect(obj.interval).toBe('day');
expect(obj.timeOfDay).toBe('14:5,35');
const result = buildCronExpression(obj);
expect(result).toBe('5,35 14 * * ? *');
});
it('should build every minute', () => {
const obj = buildCronObject('0/1 * * * ? *');
expect(obj.interval).toBe('minute');
expect(obj.minute).toBe(1);
const result = buildCronExpression(obj);
expect(result).toBe('0/1 * * * ? *');
});
it('should build every 10 minutes Monday through Friday', () => {
const obj = buildCronObject('15 5 * * 2,3,4,5,6 *');
expect(obj.interval).toBe('week');
expect(obj.timeOfDay).toBe('5:15');
expect(obj.daysOfWeek[0]).toBe(2);
expect(obj.daysOfWeek[1]).toBe(3);
expect(obj.daysOfWeek[2]).toBe(4);
expect(obj.daysOfWeek[3]).toBe(5);
expect(obj.daysOfWeek[4]).toBe(6);
const result = buildCronExpression(obj);
expect(result).toBe('15 5 * * 2,3,4,5,6 *');
});
});
That's a good first issue 😄 Thanks for the feedback and glad you're finding it useful!
It would be cool if we could merge some of that parsing I have with your lib.