cron-explain Explain cron expressions in plain English
Examples
Explain cron schedules in plain English
Usage
"*/15 9-17 * * 1-5
0 0 * * 0
30 2 1 * *" | cron-explain Verify a backup schedule runs at the right time
Usage
"0 3 * * *
0 */6 * * *" | cron-explain Understand a server maintenance window schedule
Usage
"0 9 * * 1
0 22 * * 5" | cron-explain View source
(input)=>{
const MONTHS = [
,
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
];
const DAYS = [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
];
const explain = (expr)=>{
const parts = expr.trim().split(/\s+/);
if (parts.length < 5) return `Error: need 5 fields, got ${parts.length}`;
const [min, hour, dom, mon, dow] = parts;
const bits = [];
if (min === "*") {
bits.push("Every minute");
} else if (min.startsWith("*/")) {
bits.push(`Every ${min.slice(2)} minutes`);
} else {
bits.push(`At minute ${min}`);
}
if (hour !== "*") {
if (hour.startsWith("*/")) {
bits.push(`every ${hour.slice(2)} hours`);
} else if (hour.includes("-")) {
const [a, b] = hour.split("-");
bits.push(`${a}:00\u2013${b}:00`);
} else if (hour.includes(",")) {
bits.push(`at ${hour.split(",").map((h)=>h + ":00").join(", ")}`);
} else if (!min.startsWith("*/") && min !== "*") {
bits[0] = `At ${hour.padStart(2, "0")}:${min.padStart(2, "0")}`;
} else {
bits.push(`during hour ${hour}`);
}
}
if (dom !== "*") {
if (dom.startsWith("*/")) bits.push(`every ${dom.slice(2)} days`);
else bits.push(`on day ${dom} of the month`);
}
if (mon !== "*") {
const resolve = (v)=>{
const n = parseInt(v);
return isNaN(n) ? v : MONTHS[n] || v;
};
if (mon.includes("-")) {
const [a, b] = mon.split("-");
bits.push(`in ${resolve(a)}\u2013${resolve(b)}`);
} else {
bits.push(`in ${mon.split(",").map(resolve).join(", ")}`);
}
}
if (dow !== "*") {
const resolve = (v)=>{
const n = parseInt(v);
return isNaN(n) ? v : DAYS[n] || v;
};
if (dow.includes("-")) {
const [a, b] = dow.split("-");
bits.push(`on ${resolve(a)}\u2013${resolve(b)}`);
} else {
bits.push(`on ${dow.split(",").map(resolve).join(", ")}`);
}
}
return bits.join(", ");
};
return input.trim().split("\n").map((line)=>{
line = line.trim();
if (!line) return "";
return `${line} \u2192 ${explain(line)}`;
}).join("\n");
}