⏰ 크론 표현식 해석기
크론 표현식을 넣으면 언제 실행되는지 한국어 문장과 다음 실행 시각 10개로 보여 줘요. 아래 표에서 필드를 하나씩 고쳐 직접 만들 수도 있어요.
사용법
- 맨 위 칸에 크론 표현식을 붙여넣으세요. 바로 아래에 "평일(월~금) 오전 9시 0분"처럼 한국어 설명이 나와요.
- 다음 실행 10회가 한국 시간(KST)으로 보여요. GitHub Actions·AWS처럼 서버가 UTC 기준이면 시간대를 UTC로 바꿔 확인하세요.
- 직접 만들려면 fields 표에서 분·시·일·월·요일 칸을 하나씩 고치거나 칸 아래 버튼(
*/15,1-5…)을 누르세요. 위 표현식이 함께 바뀌어요. - Spring
@Scheduled·Quartz처럼 초까지 쓰는 6자리 표현식은 그대로 넣으면 자동으로 인식해요. 초 필드 사용을 켜면 표에 초 칸이 생겨요. - 잘못된 값은 빨간 글씨로 어느 필드가 왜 틀렸는지 알려 줘요.
크론 표현식 구조
크론(cron)은 리눅스·유닉스에서 정해진 시각에 명령을 자동 실행하는 스케줄러예요. crontab -e로 등록하는 한 줄은 공백으로 나눈 다섯 칸과 실행할 명령으로 이루어져요.
| 순서 | 필드 | 허용 값 | 이름 |
|---|---|---|---|
| (0) | 초 — 6자리일 때만 | 0-59 | |
| 1 | 분 | 0-59 | |
| 2 | 시 (24시간) | 0-23 | |
| 3 | 일 | 1-31 | |
| 4 | 월 | 1-12 | JAN-DEC |
| 5 | 요일 | 0-7 (0과 7은 일요일) | SUN-SAT |
특수 문자
| 기호 | 뜻 | 예시 | 의미 |
|---|---|---|---|
| * | 모든 값 | * * * * * | 매분 |
| , | 여러 값 | 0 9,18 * * * | 오전 9시, 오후 6시 |
| - | 범위 | 0 9 * * 1-5 | 평일 오전 9시 |
| / | 간격 | */15 * * * * | 15분마다 (0, 15, 30, 45분) |
| a-b/n | 범위 안 간격 | 0 9-18/3 * * * | 9시, 12시, 15시, 18시 |
| ? | 지정 안 함 (Quartz) | 0 0 12 ? * MON | * 와 같게 처리 |
@yearly(=0 0 1 1 *), @monthly(=0 0 1 * *), @weekly(=0 0 * * 0), @daily(=0 0 * * *), @hourly(=0 * * * *) 같은 매크로도 해석해요. Quartz 전용인 L(마지막 날), W(가장 가까운 평일), #(n번째 요일)과 7번째 연도 필드는 표준 크론에 없어서 오류로 알려 줘요.
일과 요일을 둘 다 쓰면? (OR 규칙)
헷갈리기 쉬운 규칙이에요. 리눅스 기본 크론(Vixie cron, cronie)은 일 필드와 요일 필드를 둘 다 지정하면 둘 중 하나만 맞아도 실행해요. 0 0 13 * 5는 "13일의 금요일"이 아니라 매월 13일 그리고 매주 금요일마다 실행돼요. 둘 중 하나가 *로 시작하면 다른 쪽 조건만 적용돼요. 이 도구도 같은 규칙으로 다음 실행 시각을 계산해요.
자주 쓰는 예시
| 표현식 | 의미 |
|---|---|
| */5 * * * * | 5분마다 |
| 0 * * * * | 매시 정각 |
| 0 0 * * * | 매일 자정 |
| 30 6 * * * | 매일 오전 6시 30분 |
| 0 9 * * 1-5 | 평일 오전 9시 |
| */10 9-18 * * 1-5 | 평일 오전 9시~오후 6시 사이 10분마다 |
| 0 0 1 * * | 매월 1일 자정 |
| 0 3 * * 0 | 매주 일요일 오전 3시 (백업) |
| 0 0 1 1 * | 매년 1월 1일 자정 |
시간대 주의 — GitHub Actions·AWS는 UTC
서버의 크론은 그 서버의 시간대를 따라요. 한국 서버는 보통 KST지만 GitHub Actions의 schedule, AWS EventBridge, Google Cloud Scheduler 기본값, 대부분의 도커 컨테이너는 UTC예요. KST는 UTC보다 9시간 빠르니, 한국 시간 오전 9시에 돌리려면 UTC로 0 0 * * *(자정)을 써야 해요. 시간대를 UTC로 바꿔 놓고 실행 시각을 확인해 보세요. 한국은 서머타임이 없어서 KST는 1년 내내 UTC+9로 일정해요.
POSIX 크론 · 리눅스 크론 · Quartz는 문법이 달라요
"크론 표현식"이라는 이름은 같아도 표준과 구현마다 허용하는 문법이 달라요. POSIX.1-2024 crontab 명세는 숫자, 범위(1-5), 목록(1,15)과 *만 정의해요. 우리가 흔히 쓰는 */5나 MON 같은 이름은 리눅스 크론(Vixie cron·cronie)이 더한 확장이에요. Quartz CronTrigger는 초와 연도 칸이 붙고 요일 번호도 달라요.
| 항목 | POSIX | 리눅스 (cronie) | Quartz | Spring 5.3+ |
|---|---|---|---|---|
| 칸 수 | 5 | 5 | 6~7 (초·연도) | 6 (초) |
간격 / | 없음 | 있음 | 있음 | 있음 |
| 요일 번호 | 0-6 (0=일) | 0-7 (0·7=일) | 1-7 (1=일) | 0-7 (0·7=일) |
| 일·요일 둘 다 지정 | OR | OR | 불가 — 한쪽은 ? | ? 쓸 수 있음 |
L W # | 없음 | 없음 | 있음 | 있음 |
@daily 매크로 | 없음 | 있음 | 없음 | 있음 |
그래서 0 0 9 ? * 2는 Quartz에서는 월요일(1=일요일이라 2=월요일)이지만, 요일 칸만 리눅스 식으로 읽으면 화요일이에요. 이 도구는 요일 숫자를 리눅스 기준으로 풀어요. 시스템이 바뀌어도 뜻이 같게 하려면 요일은 MON처럼 영어 이름으로 쓰세요.
계산 예시 3가지 (2026-10-18 0시 KST 기준)
0 0 */2 * *— "이틀마다"의 함정: 1, 3, 5 … 31일에 실행돼요. 다음 실행은 10/19, 10/21 … 10/31(토), 11/1(일)이라 월말과 월초에는 이틀 연속으로 돌아요. 진짜 48시간 간격이 필요하면 스크립트 안에서 날짜 차이를 계산하세요.0 0 31 * *— 31일이 없는 달은 건너뜀: 10/31, 12/31, 2027-01-31, 3/31, 5/31, 7/31, 8/31 … 1년에 7번만 실행돼요. 11월·2월에는 실행되지 않아요.0 0 30 2 *처럼 존재하지 않는 날짜는 한 번도 실행되지 않고, 이 도구도 다음 실행 시각을 비워 둬요.0 0 13 * 5— OR 규칙: 다음 실행이 10/23(금), 10/30(금), 11/6(금), 11/13(금) … 이에요. 13일의 금요일만이 아니라 매주 금요일과 매월 13일(예: 2026-12-13 일요일)에도 실행돼요.
흔한 실수와 바로잡기
| 증상 | 원인 | 바로잡기 |
|---|---|---|
date +%Y%m%d가 든 줄이 잘려서 실행됨 | crontab에서 %는 줄바꿈으로 바뀌어요 (POSIX 규칙) | \%로 이스케이프하거나 스크립트 파일로 빼기 |
| 터미널에선 되는데 크론에선 "command not found" | 크론의 PATH가 /usr/bin:/bin 정도로 짧아요 | 명령을 절대 경로로 쓰거나 crontab 맨 위에 PATH= 지정 |
| 9시간 어긋나서 실행 | 서버·클라우드가 UTC | 위 시간대를 UTC로 바꿔 확인, KST − 9시간으로 작성 |
| 앞 작업이 안 끝났는데 또 실행 | 크론은 겹침을 막지 않아요 | flock -n /tmp/job.lock 명령으로 중복 실행 방지 |
| Spring에 5자리 넣었더니 오류 | Spring은 초 포함 6자리 | 맨 앞에 0 추가 (0 0 9 * * *) |
다음 실행 시각을 Unix 타임스탬프로 확인하려면 타임스탬프 변환기, 스크립트 파일 권한(chmod +x, 755)은 chmod 권한 계산기에서 볼 수 있어요.
요일 번호는 표준 크론 기준(0·7=일, 1=월)이에요. Quartz는 1=일요일, 7=토요일로 달라서 요일을 숫자 대신 MON·FRI 같은 영어 이름으로 쓰면 어느 쪽에서도 안전해요. 다음 실행 시각은 브라우저의 현재 시각을 기준으로 계산하며 서버로 아무것도 보내지 않아요.