Sohail @chakraframer.com
Posted on October 29, 2024
So, I had a cron server running multiple tasks. I had a task lets call to it x-task
that was supposed to run every day 5.00 PM and few others that supposed to run at different times. I had scheduled them using cron package.
But the problem was that x-task
was running multiple times in a day instead of one time in a at @5.00 PM. I was confused as I had took cron time syntax from cron guru it was 0 17 * * *
link1, link2. Lets see what was the problem and how we can prevent it.
Also I have attached a cool cronjob code snippet for you to use for all your cron jobs. And here is the guide to setup cron in node.js
Prerequisites
- Basic knowledge of JavaScript and Node.js
- Basic knowledge of npm
- Basic knowledge of Node.js and Express.js
- Basic knowledge of cronjob schedule
So If you dont know about cronjob schedule you can learn about it here
Lets break down the task into smaller steps.
Step 1: Identify the problem
So the problem was cron uses uses 6 parameters to define the schedule but in general cronjob uses 5 parameters. Please see below for the explanation of the parameters.
cron parameters
- Seconds
- Minutes
- Hours
- Day of the month
- Month
- Day of the week
General cronjob parameters
- Minutes
- Hours
- Day of the month
- Month
- Day of the week
You can see that cron package uses extra parameter in starting which is seconds. So when you define a cronjob schedule in cron package you have to provide 6 parameters.
Step 2: Fixing the problem
So the problem was that I was using 0 17 * * *
as a cronjob schedule which was wrong. The correct schedule should be 0 0 17 * * *
. So the correct schedule for the task to run at 5.00 PM should be 0 0 17 * * *
. So I changed the schedule and the task was running only once in a day.
Cool cronjob code snippet
Copy the below code snippet and paste it in any file in your project. You can use this code snippet to generate cron expressions for different time intervals with 6 fields for cron without scheduling the task wrong ever again 😄. Also If your not familiar with typescript I have attached JavaScript version.
TypeScript Version
/**
* @description Generate cron expressions for different time intervals with 6 fields for cron CronJob
*/
export class CronTime {
// Generate a cron expression for every month on a specified day
// Example: everyMonthOn(15) -> "0 0 0 15 * *"
static everyMonthOn(day: number = 1, hour: number = 0): string {
if (day < 1 || day > 31) {
throw new Error('Day must be between 1 and 31')
}
if (hour < 0 || hour > 23) {
throw new Error('Hour must be between 0 and 23')
}
return `0 0 ${hour} ${day} * *`
}
// Generate a cron expression for every day of the week at a specified hour
// Example: everyDay(3) -> "0 0 3 * * *"
static everyDay(hour: number = 0): string {
if (hour < 0 || hour > 23) {
throw new Error('Hour must be between 0 and 23')
}
return `0 0 ${hour} * * *`
}
// Generate a cron expression for every Monday at a specified hour
// Example: everyMonday(2) -> "0 0 2 * * 1"
static everyMonday(hour: number = 0): string {
return CronTime.everyWeekday(1, hour)
}
// Generate a cron expression for every Tuesday at a specified hour
// Example: everyTuesday(3) -> "0 0 3 * * 2"
static everyTuesday(hour: number = 0): string {
return CronTime.everyWeekday(2, hour)
}
// Generate a cron expression for every Wednesday at a specified hour
// Example: everyWednesday(4) -> "0 0 4 * * 3"
static everyWednesday(hour: number = 0): string {
return CronTime.everyWeekday(3, hour)
}
// Generate a cron expression for every Thursday at a specified hour
// Example: everyThursday(5) -> "0 0 5 * * 4"
static everyThursday(hour: number = 0): string {
return CronTime.everyWeekday(4, hour)
}
// Generate a cron expression for every Friday at a specified hour
// Example: everyFriday(6) -> "0 0 6 * * 5"
static everyFriday(hour: number = 0): string {
return CronTime.everyWeekday(5, hour)
}
// Generate a cron expression for every Saturday at a specified hour
// Example: everySaturday(7) -> "0 0 7 * * 6"
static everySaturday(hour: number = 0): string {
return CronTime.everyWeekday(6, hour)
}
// Generate a cron expression for every Sunday at a specified hour
// Example: everySunday(8) -> "0 0 8 * * 0"
static everySunday(hour: number = 0): string {
return CronTime.everyWeekday(0, hour)
}
// Helper method for generating a cron expression for a specific weekday
private static everyWeekday(dayOfWeek: number, hour: number): string {
if (hour < 0 || hour > 23) {
throw new Error('Hour must be between 0 and 23')
}
if (dayOfWeek < 0 || dayOfWeek > 6) {
throw new Error('Day of week must be between 0 (Sunday) and 6 (Saturday)')
}
return `0 0 ${hour} * * ${dayOfWeek}`
}
// Generate a cron expression for every hour
static everyHour(): string {
return '0 0 * * * *'
}
// Generate a cron expression for every minute
static everyMinute(): string {
return '0 * * * * *'
}
// Generate a cron expression for every N seconds
static everyNSeconds(seconds: number): string {
if (seconds <= 0 || seconds > 59) {
throw new Error('Seconds must be between 1 and 59')
}
return `*/${seconds} * * * * *`
}
// Generate a cron expression for every N minutes
// Example: everyNMinutes(15) -> "0 */15 * * * *"
static everyNMinutes(minutes: number): string {
if (minutes <= 0 || minutes > 59) {
throw new Error('Minutes must be between 1 and 59')
}
return `0 */${minutes} * * * *`
}
// Generate a cron expression for every N hours
// Example: everyNHours(3) -> "0 0 */3 * * *"
static everyNHours(hours: number): string {
if (hours <= 0 || hours > 23) {
throw new Error('Hours must be between 1 and 23')
}
return `0 0 */${hours} * * *`
}
// Generate a cron expression for a specific time on a specific day of the week
// Example: atHourOnDayOfWeek(3, 5) -> "0 0 3 * * 5"
static atHourOnDayOfWeek(hour: number, dayOfWeek: number): string {
return CronTime.everyWeekday(dayOfWeek, hour)
}
// Generate a cron expression for a specific time every month on a specific date
// Example: atHourOnDayOfMonth(15, 5) -> "0 0 5 15 * *"
static atHourOnDayOfMonth(day: number, hour: number): string {
return CronTime.everyMonthOn(day, hour)
}
}
JavaScript Version
/**
* @description Generate cron expressions for different time intervals with 6 fields for cron CronJob
*/
class CronTime {
// Generate a cron expression for every month on a specified day
// Example: everyMonthOn(15) -> "0 0 0 15 * *"
static everyMonthOn(day = 1, hour = 0) {
if (day < 1 || day > 31) {
throw new Error('Day must be between 1 and 31')
}
if (hour < 0 || hour > 23) {
throw new Error('Hour must be between 0 and 23')
}
return `0 0 ${hour} ${day} * *`
}
// Generate a cron expression for every day of the week at a specified hour
// Example: everyDay(3) -> "0 0 3 * * *"
static everyDay(hour = 0) {
if (hour < 0 || hour > 23) {
throw new Error('Hour must be between 0 and 23')
}
return `0 0 ${hour} * * *`
}
// Generate a cron expression for every Monday at a specified hour
// Example: everyMonday(2) -> "0 0 2 * * 1"
static everyMonday(hour = 0) {
return CronTime.everyWeekday(1, hour)
}
// Generate a cron expression for every Tuesday at a specified hour
// Example: everyTuesday(3) -> "0 0 3 * * 2"
static everyTuesday(hour = 0) {
return CronTime.everyWeekday(2, hour)
}
// Generate a cron expression for every Wednesday at a specified hour
// Example: everyWednesday(4) -> "0 0 4 * * 3"
static everyWednesday(hour = 0) {
return CronTime.everyWeekday(3, hour)
}
// Generate a cron expression for every Thursday at a specified hour
// Example: everyThursday(5) -> "0 0 5 * * 4"
static everyThursday(hour = 0) {
return CronTime.everyWeekday(4, hour)
}
// Generate a cron expression for every Friday at a specified hour
// Example: everyFriday(6) -> "0 0 6 * * 5"
static everyFriday(hour = 0) {
return CronTime.everyWeekday(5, hour)
}
// Generate a cron expression for every Saturday at a specified hour
// Example: everySaturday(7) -> "0 0 7 * * 6"
static everySaturday(hour = 0) {
return CronTime.everyWeekday(6, hour)
}
// Generate a cron expression for every Sunday at a specified hour
// Example: everySunday(8) -> "0 0 8 * * 0"
static everySunday(hour = 0) {
return CronTime.everyWeekday(0, hour)
}
// Helper method for generating a cron expression for a specific weekday
static everyWeekday(dayOfWeek, hour) {
if (hour < 0 || hour > 23) {
throw new Error('Hour must be between 0 and 23')
}
if (dayOfWeek < 0 || dayOfWeek > 6) {
throw new Error('Day of week must be between 0 (Sunday) and 6 (Saturday)')
}
return `0 0 ${hour} * * ${dayOfWeek}`
}
// Generate a cron expression for every hour
static everyHour() {
return '0 0 * * * *'
}
// Generate a cron expression for every minute
static everyMinute() {
return '0 * * * * *'
}
// Generate a cron expression for every N seconds
static everyNSeconds(seconds) {
if (seconds <= 0 || seconds > 59) {
throw new Error('Seconds must be between 1 and 59')
}
return `*/${seconds} * * * * *`
}
// Generate a cron expression for every N minutes
// Example: everyNMinutes(15) -> "0 */15 * * * *"
static everyNMinutes(minutes) {
if (minutes <= 0 || minutes > 59) {
throw new Error('Minutes must be between 1 and 59')
}
return `0 */${minutes} * * * *`
}
// Generate a cron expression for every N hours
// Example: everyNHours(3) -> "0 0 */3 * * *"
static everyNHours(hours) {
if (hours <= 0 || hours > 23) {
throw new Error('Hours must be between 1 and 23')
}
return `0 0 */${hours} * * *`
}
// Generate a cron expression for a specific time on a specific day of the week
// Example: atHourOnDayOfWeek(3, 5) -> "0 0 3 * * 5"
static atHourOnDayOfWeek(hour, dayOfWeek) {
return CronTime.everyWeekday(dayOfWeek, hour)
}
// Generate a cron expression for a specific time every month on a specific date
// Example: atHourOnDayOfMonth(15, 5) -> "0 0 5 15 * *"
static atHourOnDayOfMonth(day, hour) {
return CronTime.everyMonthOn(day, hour)
}
}
Conclusion
So, I hope you find this article helpful. If you have any questions, feel free to ask in the comments below or contact me on Twitter/X @thesohailjafri.
Also save this article for future reference so you dont schedule your cron jobs wrong ever again 😄.
Posted on October 29, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.