pipr.tools
Pipes
Clean Email Strip formatting from pasted email for clean plain text Clean AI Output Clean plain text from ChatGPT or AI output Decode & Format JWT Decode a JWT and pretty-print header and payload Word Frequency Count word frequency in text

cron-explain Explain cron expressions in plain English

⇔ Decode
Input0 chars
Output0 chars

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");
            }

Related Tools