EventBridge cron 식 작성법: ?의 의미·요일 숫자·일본 시간 지정과 crontab에서 바꿔 쓰기
AWS에서 Lambda나 ECS 태스크를 정기 실행할 때 쓰는 EventBridge cron 식은 Linux crontab과 비슷해 보이지만 필드 수, ? 사용법, 요일 숫자, 시간대가 조금씩 다릅니다. crontab 감각으로 "0 9 * * 1-5"라고 쓰면 오류가 나고, 요일 숫자를 그대로 옮기면 하루가 밀리며, 시각은 UTC로 해석되어 9시간 어긋나는 등 걸림돌이 겹칩니다. 이 글에서는 EventBridge cron 식의 6개 필드와 ? 규칙, 요일 숫자, L·W·# 사용법, rate 식과의 차이, 규칙과 Scheduler에서 일본 시간을 다루는 방법, crontab·Kubernetes·Spring·systemd와의 변환표까지 정리합니다.
EventBridge cron 식은 "6개 필드"를 cron( )으로 감싼다
EventBridge 스케줄은 cron( )이나 rate( ) 중 하나로 씁니다. cron( ) 안에는 crontab의 5개 필드에 "연도"를 더한 6개 값을 공백으로 구분해 나열합니다. 연도 필드는 생략할 수 없으므로 연도를 가리지 않을 때도 끝에 *를 씁니다.
| 순서 | 필드 | 쓸 수 있는 값 | 쓸 수 있는 기호 |
|---|---|---|---|
| 1번째 | 분 | 0~59 | , - * / |
| 2번째 | 시 | 0~23 | , - * / |
| 3번째 | 일 | 1~31 | , - * ? / L W |
| 4번째 | 월 | 1~12 또는 JAN~DEC | , - * / |
| 5번째 | 요일 | 1~7 또는 SUN~SAT | , - * ? L # |
| 6번째 | 연도 | 1970~2199 | , - * / |
예를 들어 "평일(월~금) 0:00(UTC)"은 "cron(0 0 ? * MON-FRI *)"입니다. crontab의 "0 0 * * 1-5"와 비교하면 날짜 필드가 ?가 되고, 요일이 영어 약칭이 되고, 마지막에 연도의 *가 늘었습니다. 이 세 곳이 crontab에서 옮길 때 반드시 고쳐야 하는 부분입니다.
? 규칙: 날짜나 요일 중 하나는 반드시 ?로
EventBridge에서 가장 오류가 나기 쉬운 것이 ? 처리입니다. ?는 "이 필드에서는 지정하지 않는다(다른 필드로 정한다)"는 뜻이며, 날짜(3번째)나 요일(5번째) 중 정확히 한쪽에 씁니다. 둘 다 *로 할 수도, 둘 다 ?로 할 수도 없습니다.
| 하고 싶은 것 | 올바른 표기 | 흔한 실수 |
|---|---|---|
| 매일 9:00 | cron(0 9 * * ? *) | cron(0 9 * * * *)(둘 다 *) |
| 평일 9:00 | cron(0 9 ? * MON-FRI *) | cron(0 9 * * MON-FRI *)(날짜가 *) |
| 매월 1일 9:00 | cron(0 9 1 * ? *) | cron(0 9 1 * * *)(요일이 *) |
| 매주 월요일 9:00 | cron(0 9 ? * MON *) | cron(0 9 ? * ? *)(둘 다 ?) |
외우는 법은 간단합니다. "요일로 정하면 날짜를 ?, 날짜로 정하면 요일을 ?, 매일이면 날짜를 *로 하고 요일을 ?"입니다. 이 구조 때문에 crontab 같은 "날짜나 요일 중 하나(OR)"도, Spring 같은 "둘 다(AND)"도 규칙 하나로는 쓸 수 없습니다. "매월 1일과 매주 금요일" 같은 지정은 날짜 규칙과 요일 규칙 두 개로 나눕니다.
요일 숫자는 1이 일요일: crontab과 하나 어긋난다
crontab에서는 0이 일요일, 1이 월요일이지만 EventBridge에서는 1이 일요일, 2가 월요일…7이 토요일입니다. 숫자를 그대로 옮기면 모든 요일이 하루 앞당겨집니다.
| 요일 | crontab | EventBridge | 영어 약칭 |
|---|---|---|---|
| 일요일 | 0(7도 가능) | 1 | SUN |
| 월요일 | 1 | 2 | MON |
| 화요일 | 2 | 3 | TUE |
| 수요일 | 3 | 4 | WED |
| 목요일 | 4 | 5 | THU |
| 금요일 | 5 | 6 | FRI |
| 토요일 | 6 | 7 | SAT |
| 평일(월~금) | 1-5 | 2-6 | MON-FRI |
crontab의 "1-5"를 그대로 EventBridge에 쓰면 일요일~목요일(SUN-THU)이 되어, 월요일 처리가 일요일에 실행되고 금요일에는 실행되지 않는 알아차리기 어려운 문제가 생깁니다. EventBridge에서는 MON-FRI처럼 영어 약칭으로 쓰면 숫자 어긋남을 신경 쓰지 않아도 되므로 추천합니다.
L·W·#로 월말·평일·n번째 요일을 쓴다
EventBridge cron 식은 crontab으로는 쓸 수 없는 "월말", "n번째 ○요일" 등을 직접 나타낼 수 있습니다. 일간·월간 배치에서 자주 쓰므로 대표적인 표기를 외워 두면 편리합니다.
| 표기 | 의미 | 식 예시 | 2026년 10월 이후 실행일 |
|---|---|---|---|
| 날짜의 L | 그달의 말일 | cron(0 0 L * ? *) | 10/31·11/30·12/31·1/31·2/28 |
| 날짜의 L-3 | 말일 3일 전 | cron(0 9 L-3 * ? *) | 10/28·11/27·12/28 |
| 날짜의 15W | 15일에 가장 가까운 평일 | cron(0 9 15W * ? *) | 10/15(목)·11/16(월)·12/15(화) |
| 날짜의 LW | 그달의 마지막 평일 | cron(0 18 LW * ? *) | 10/30(금)·11/30(월)·12/31(목) |
| 요일의 3#2 | 둘째 화요일(3이 화요일) | cron(0 10 ? * 3#2 *) | 10/13·11/10·12/8 |
| 요일의 6L | 마지막 금요일(6이 금요일) | cron(0 18 ? * 6L *) | 10/30·11/27·12/25 |
#와 L은 요일 숫자와 조합하므로 여기서도 "1이 일요일"인 어긋남에 주의해야 합니다. crontab 감각으로 둘째 화요일을 "2#2"라고 쓰면 둘째 월요일이 됩니다. W는 "지정한 날이 토·일이면 같은 달 안에서 가장 가까운 평일"에 실행되며 달을 넘지 않습니다. 2026년 11월 15일은 일요일이므로 15W는 다음 날인 16일(월)에 실행됩니다.
rate 식과의 차이: "~마다"는 시작한 시각부터 센다
단순한 간격이라면 cron 대신 rate( )도 쓸 수 있습니다. rate(5 minutes)·rate(1 hour)·rate(7 days)처럼 숫자와 단위(minute·hour·day)를 씁니다.
- 1일 때는 단수형, 2 이상은 복수형으로 쓴다. rate(1 hours)나 rate(5 minute)는 오류가 난다
- 간격은 규칙을 만든(또는 활성화한) 시각부터 세므로 "매시 0분"처럼 시각을 맞출 수 없다
- "매시 0·15·30·45분 정각"에 실행하고 싶다면 rate(15 minutes)가 아니라 cron(0/15 * * * ? *)를 쓴다
- 주나 월 단위는 없으므로 매주·매월 처리는 cron으로 쓴다
EventBridge cron 식에서는 간격의 시작을 "0/15"처럼 숫자로 쓰는 것이 일반적입니다("*/15"와 같은 뜻입니다). 로그 집계처럼 시각이 맞아야 나중에 다루기 쉬운 처리는 cron, 헬스 체크처럼 간격만 중요한 처리는 rate로 나눠 쓰면 좋습니다.
일본 시간으로 실행하기: 규칙은 UTC, Scheduler는 시간대를 고를 수 있다
EventBridge에는 스케줄을 만드는 방법이 두 가지 있습니다. 예전부터 있던 "EventBridge 규칙(Rules)"과 2022년에 추가된 "EventBridge Scheduler"입니다. cron 식 작성법은 같지만 시간대 처리가 다릅니다.
| EventBridge 규칙 | EventBridge Scheduler | |
|---|---|---|
| cron 식의 시간대 | UTC 고정 | ScheduleExpressionTimezone으로 지정(Asia/Tokyo 등) |
| 평일 9:00(일본 시간) 작성법 | cron(0 0 ? * MON-FRI *) | cron(0 9 ? * MON-FRI *) + 시간대 Asia/Tokyo |
| 한 번만 실행 | 불가 | at(2026-12-01T09:00:00)으로 지정 가능 |
| 서머타임이 있는 지역 | 직접 시각을 고쳐야 한다 | 시간대에 맞춰 자동 조정 |
규칙으로 일본 시간에 맞추려면 GitHub Actions와 마찬가지로 9시간을 뺀 UTC 시각을 씁니다. 일본 시간 0~8시대는 UTC로 전날이 되므로 요일도 하나 되돌립니다. 예를 들어 일본 시간 평일 8:00은 UTC 일~목 23:00이므로 "cron(0 23 ? * SUN-THU *)"입니다. 이 계산의 자세한 순서는 GitHub Actions cron을 일본 시간으로 실행하는 방법에서 설명합니다. 새로 만든다면 시간대를 지정할 수 있는 Scheduler를 쓰는 편이 시차 계산 실수가 없어 안전합니다. 한국 시간(KST)도 UTC+9라서 계산은 같습니다.
crontab·Kubernetes·Spring·systemd와의 변환표
같은 스케줄을 자주 쓰는 시스템별 표기로 나란히 정리했습니다. 시각은 각 시스템에서 지정한 시간대 기준입니다(EventBridge 규칙과 GitHub Actions는 UTC).
| 스케줄 | crontab·Kubernetes | EventBridge | Spring @Scheduled | systemd OnCalendar |
|---|---|---|---|---|
| 매일 3:30 | 30 3 * * * | cron(30 3 * * ? *) | 0 30 3 * * * | *-*-* 03:30:00 |
| 평일 9:00 | 0 9 * * 1-5 | cron(0 9 ? * MON-FRI *) | 0 0 9 * * MON-FRI | Mon..Fri *-*-* 09:00:00 |
| 15분마다 | */15 * * * * | cron(0/15 * * * ? *) | 0 */15 * * * * | *-*-* *:00/15:00 |
| 매월 1일 0:00 | 0 0 1 * * | cron(0 0 1 * ? *) | 0 0 0 1 * * | *-*-01 00:00:00 |
| 매월 말일 23:00 | 쓸 수 없음(28-31 + 판정) | cron(0 23 L * ? *) | 0 0 23 L * * | *-*~01 23:00:00 |
| 둘째 화요일 10:00 | 쓸 수 없음(8-14 + 판정) | cron(0 10 ? * 3#2 *) | 0 0 10 ? * TUE#2 | Tue *-*-08..14 10:00:00 |
- Kubernetes CronJob은 crontab과 같은 5개 필드. 1.27 이후는 spec.timeZone: Asia/Tokyo로 일본 시간을 지정할 수 있고, schedule 안에 CRON_TZ=를 쓰는 방법은 쓸 수 없다
- Spring은 맨 앞에 초 필드가 있는 6개 필드. @Scheduled(cron = "0 0 9 * * MON-FRI", zone = "Asia/Tokyo")처럼 zone으로 시간대를 지정할 수 있다
- systemd timer의 OnCalendar는 "요일 연-월-일 시:분:초" 형식. ~01은 "월말부터 세어 1일째", 즉 말일을 나타낸다
cron 식 검사기에서 표기 종류로 AWS EventBridge를 고르고 식을 붙여 넣으면 ? 누락이나 요일 숫자 어긋남을 알려 주고, 해석과 다음 실행 일시를 표시합니다. crontab 식을 넣으면 EventBridge·Kubernetes·Spring·systemd 표기로 바꾼 결과도 한 번에 확인할 수 있습니다. 날짜·요일 OR의 차이가 얽힌 이식은 cron의 날짜·요일 OR 규칙과 n번째 요일·월말 작성법도 함께 확인하세요.
자주 묻는 질문
- EventBridge cron 식의 ?는 무슨 뜻인가요?
- "이 필드에서는 지정하지 않는다"는 뜻으로, 날짜나 요일 중 한쪽에 반드시 씁니다. 요일로 정하면 날짜를 ?, 날짜로 정하면 요일을 ?로 합니다. 매일이라면 cron(0 9 * * ? *)처럼 날짜를 *, 요일을 ?로 합니다. 둘 다 *나 둘 다 ?는 오류가 납니다.
- EventBridge로 일본 시간 9시에 실행하려면 어떻게 쓰나요?
- EventBridge 규칙은 UTC로 해석되므로 9시간을 빼서 cron(0 0 * * ? *)로 씁니다. EventBridge Scheduler라면 cron(0 9 * * ? *)로 쓰고 시간대(ScheduleExpressionTimezone)에 Asia/Tokyo를 지정하면 일본 시간 9:00에 실행됩니다.
- EventBridge 요일 숫자에서 월요일은 몇 번인가요?
- 1이 일요일, 2가 월요일…7이 토요일입니다. crontab(0이 일요일, 1이 월요일)과 하나 어긋나 있어 평일은 2-6이 됩니다. 숫자 착오를 막으려면 MON-FRI처럼 영어 약칭으로 쓰는 것을 추천합니다.
- EventBridge로 5분마다 실행하려면 cron과 rate 중 무엇이 좋나요?
- 간격만 중요하다면 rate(5 minutes)가 간단합니다. 다만 rate는 규칙을 만든 시각부터 세기 때문에 실행 시각이 매시 0·5·10분에 맞춰지지 않습니다. 시각을 맞추고 싶다면 cron(0/5 * * * ? *)를 씁니다.
- crontab의 "0 9 * * 1-5"는 EventBridge에서 어떻게 바꿔 쓰나요?
- 날짜를 ?, 요일을 MON-FRI(숫자라면 2-6)로 하고 마지막에 연도의 *를 더해 cron(0 9 ? * MON-FRI *)로 합니다. 또한 EventBridge 규칙은 UTC로 해석되므로 일본 시간 9:00에 실행하려면 시를 0으로 해서 cron(0 0 ? * MON-FRI *)로 합니다.
이 글에서 소개한 도구
함께 읽으면 좋은 글
GitHub Actions cron을 일본 시간으로 실행하기: UTC 변환표와 요일 밀림·지연 대책
GitHub Actions의 schedule에 "0 9 * * 1-5"라고 썼는데 워크플로가 일본 시간 오후 6시에 실행됐다면, 오타가 아니라 GitHub Actions의 cron이 항상 UTC(협정 세계시)로 해석되기 때문입니다. 이 글에서는 일본 시간(JST)을 UTC cron 식으로 바꾸는 계산과 변환표, 오전 0~8시를 지정할 때 생기는 "요일·날짜가 전날로 밀리는" 문제, 한 줄로 쓸 수 없을 때 두 줄로 나누는 방법, schedule이 늦거나 실행되지 않을 때의 원인과 대책을 정리합니다. 한국 표준시(KST)도 UTC+9라서 같은 표를 그대로 쓸 수 있습니다.
글 읽기 →crontab 작성법과 빠른 참조표: 5개 필드와 기호의 의미, 자주 쓰는 예, 등록 명령
"매일 3시에 백업", "5분마다 모니터링 스크립트" 같은 정기 실행은 Linux에서는 crontab에 한 줄만 쓰면 설정할 수 있습니다. 하지만 "분 시 일 월 요일" 5개 필드와 * , - / 기호의 조합은 익숙해지기 전까지 잘못 읽기 쉬워서, 1시간에 60번 실행되거나 7분마다 돌리려던 것이 4분 간격이 되는 사고도 자주 일어납니다. 이 글에서는 crontab 작성법의 기본과 기호의 의미, 그대로 쓸 수 있는 빠른 참조표, crontab -e·-l·-r 사용법, 명령 부분을 쓸 때의 주의점을 예시 중심으로 설명합니다.
글 읽기 →cron의 날짜와 요일은 OR: 둘째 월요일·월말·마지막 금요일·격주를 올바르게 쓰는 법
"매월 첫째 월요일 9시"라는 생각으로 "0 9 1-7 * 1"이라고 썼더니 매주 월요일에 더해 매월 1~7일 매일에도 실행됐다. cron에서 아주 흔한 이 실수는 날짜와 요일을 둘 다 지정하면 "둘 중 하나"에 해당하는 날에 실행된다는 cron 특유의 규칙 때문입니다. 이 글에서는 날짜와 요일이 OR이 되는 원리와 예외, crontab에서 n번째 요일·월말·마지막 금요일·격주를 올바르게 실행하는 방법, AWS EventBridge와 Spring에서 쓸 수 있는 L·#·W 표기까지 실제 실행 날짜 예시와 함께 설명합니다.
글 읽기 →