Cron Expression Validator
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 표현식은 반복 스케줄을 정의하는 5개의 공백으로 구분된 필드(분, 시, 월별 일, 월, 요일)를 사용합니다. 필드 중 하나라도 허용 범위를 벗어난 값, 잘못된 연산자, 또는 잘못된 필드 수와 같은 구조적 오류를 포함하면, 표현식은 배포 시 스케줄러에 의해 거부되거나 트리거 시간과 무관하게 조용히 실패합니다.
Cron 표현식을 온라인으로 검사하면 프로덕션에 배포하여 누락된 작업을 기다리는 것보다 오류를 더 일찍 발견할 수 있습니다. 대표적인 실수로는 시 필드에 25를 입력하는 것(유효 범위: 0-23), 스텝 값으로 0을 사용하는 것(*/0은 정의되지 않음), 범위 경계를 반전시키는 것(1-5 대신 5-1), 또는 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 표현식 vs. 유효하지 않은 표현식
올바른 형식의 표현식과 자주 발생하는 실수를 빠르게 비교합니다. 스케줄러 설정에 붙여넣기 전에 표현식을 확인하는 데 활용하세요.
코드 예제
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"