Cron 表达式验证器
验证 cron 表达式并查看详细的逐字段分解
Cron 表达式
minute hour day(month) month day(week)
字段说明
*/15(0–59)展开为: 0, 15, 30, 45
0-6(0–23)展开为: 0, 1, 2, 3, 4, 5, 6
1,15(1–31)展开为: 1, 15
*(1–12)展开为: all (1–12)
1-5(0–6)展开为: 1, 2, 3, 4, 5
什么是 Cron 表达式验证?
Cron 表达式验证是指在表达式送入调度器之前,检查其是否符合正确语法规则的过程。Cron 表达式由五个空格分隔的字段组成(分钟、小时、月份中的日期、月份、星期几),用于定义周期性计划。如果任意字段包含超出范围的值、无效运算符,或字段数量不对等结构性错误,该表达式要么在部署时被调度器拒绝,要么静默失效、永不触发。
在线验证 cron 表达式比部署到生产环境后等待任务遗漏更早发现错误。常见错误包括:在小时字段写 25(有效范围为 0-23)、使用步长为零(*/0,未定义行为)、反转范围边界(5-1 而非 1-5),或添加属于非标准格式(如 Quartz)的额外字段。语法检查器能即刻标记这些问题,并精确告知哪个字段有误。
Cron 验证与 cron 解析不同。解析器接受有效表达式并将其转换为人类可读的计划描述;验证器回答一个更简单的问题:这个表达式格式是否正确?应先验证再解析——将无效表达式送入调度器毫无意义。在 CI/CD 管道中,自动化 cron 验证可防止格式错误的计划被合并进配置文件。
为什么使用这个 Cron 验证器?
Cron 表达式有严格的语法规则,而各调度器在规则被破坏时给出的错误信息参差不齐。有些调度器抛出晦涩的错误,有些则静默接受、从不触发。本验证器在部署前为您提供清晰的逐字段诊断。
Cron 验证器使用场景
常见 Cron 语法错误
下表列出了最常见的 cron 表达式错误及其原因。这些是在生产配置和 CI/CD 管道中反复出现的错误。
| 错误类型 | 示例 | 错误原因 |
|---|---|---|
| Too few fields | 0 9 * * | Missing the day-of-week field. Standard cron requires exactly 5 fields. |
| Too many fields | 0 0 9 * * 1 2026 | Extra fields. Some tools add seconds or year, but standard cron uses 5. |
| Value out of range | 0 25 * * * | Hour field accepts 0-23. Value 25 exceeds the maximum. |
| Invalid step base | 0 0 32/2 * * | Day-of-month starts at 32, which exceeds the 1-31 range. |
| Step of zero | */0 * * * * | Step value must be 1 or greater. Zero creates an infinite loop. |
| Empty field | 0 9 * * 1 | Double space creates an empty field. Each field needs a value. |
| Invalid character | 0 9 * * Mon-Fry | Typo in day name. Use three-letter abbreviations: MON, TUE, WED, THU, FRI, SAT, SUN. |
| Reversed range | 0 9 * * 5-1 | Range end (1) is less than start (5). Write 1-5 or use a list: 5,6,0,1. |
有效与无效的 Cron 表达式
有效表达式与常见错误的快速对照参考。在将表达式粘贴到调度器配置前用于自查。
代码示例
如何在 JavaScript、Python、Go 和 Bash 中以编程方式验证 cron 表达式。每个示例展示如何捕获无效语法并提取有意义的错误信息。
import { parseExpression } from 'cron-parser';
// Validate a cron expression by attempting to parse it
function validateCron(expr) {
try {
parseExpression(expr);
return { valid: true, error: null };
} catch (err) {
return { valid: false, error: err.message };
}
}
console.log(validateCron('0 9 * * 1-5'));
// → { valid: true, error: null }
console.log(validateCron('0 25 * * *'));
// → { valid: false, error: "Constraint error, got value 25 expected range 0-23" }
// Validate with field-level detail using cron-validator
import { isValidCron } from 'cron-validator';
isValidCron('*/15 * * * *'); // → true
isValidCron('*/15 * * * *', { seconds: true }); // → false (expects 6 fields)
isValidCron('0 0 31 2 *'); // → true (syntactically valid, Feb 31 never fires)from croniter import croniter
# Validate by checking if croniter can parse the expression
def validate_cron(expr: str) -> dict:
if croniter.is_valid(expr):
return {"valid": True, "error": None}
# Get a more specific error message
try:
croniter(expr)
except (ValueError, KeyError) as e:
return {"valid": False, "error": str(e)}
return {"valid": False, "error": "Unknown error"}
print(validate_cron("0 9 * * 1-5"))
# → {'valid': True, 'error': None}
print(validate_cron("0 25 * * *"))
# → {'valid': False, 'error': '...out of range...'}
print(validate_cron("* * *"))
# → {'valid': False, 'error': 'Exactly 5 or 6 columns...'}
# Field-level validation
from crontab import CronTab
cron = CronTab(tab="")
job = cron.new(command="/bin/true")
try:
job.setall("0 9 * * 1-5")
print(job.is_valid()) # → True
except Exception as e:
print(f"Invalid: {e}")package main
import (
"fmt"
"github.com/robfig/cron/v3"
)
// ValidateCron checks whether a 5-field cron expression is syntactically correct
func ValidateCron(expr string) (bool, error) {
parser := cron.NewParser(
cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow,
)
_, err := parser.Parse(expr)
if err != nil {
return false, err
}
return true, nil
}
func main() {
exprs := []string{
"0 9 * * 1-5", // valid
"0 25 * * *", // invalid: hour 25
"*/15 * * * *", // valid
"0 0 32 * *", // invalid: day 32
}
for _, e := range exprs {
ok, err := ValidateCron(e)
if ok {
fmt.Printf("%-20s VALID
", e)
} else {
fmt.Printf("%-20s INVALID: %v
", e, err)
}
}
}#!/bin/bash
# Validate cron syntax using Python one-liner
validate_cron() {
python3 -c "
from croniter import croniter
import sys
expr = sys.argv[1]
if croniter.is_valid(expr):
print(f'VALID: {expr}')
sys.exit(0)
else:
print(f'INVALID: {expr}')
sys.exit(1)
" "$1"
}
validate_cron "0 9 * * 1-5" # → VALID: 0 9 * * 1-5
validate_cron "0 25 * * *" # → INVALID: 0 25 * * *
# Quick regex pre-check (catches field count and obvious issues)
cron_regex='^([0-9*/,-]+\s+){4}[0-9*/,-]+$'
echo "*/5 * * * *" | grep -Eq "$cron_regex" && echo "passes basic check"
echo "* * *" | grep -Eq "$cron_regex" || echo "fails basic check"