사용 가이드게시일 읽는 시간 약 10분

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라서 같은 표를 그대로 쓸 수 있습니다.

왜 9시간 어긋날까? GitHub Actions cron은 UTC 고정

GitHub Actions에서는 워크플로 YAML에 on.schedule과 cron 식을 쓰면 정해진 시각에 작업을 실행할 수 있습니다. 이때 cron 식은 저장소 소유자가 어느 나라에 있든, 러너가 어디에 있든 UTC(협정 세계시)로 해석됩니다. PC 시계나 저장소 설정에 맞춰 일본 시간으로 바꿔 읽어 주지 않습니다.

일본 시간(JST)은 UTC보다 9시간 빠릅니다. 즉 UTC 0:00은 일본의 9:00, UTC 9:00은 일본의 18:00입니다. 일본 시간이라고 생각하고 "0 9 * * *"라고 쓰면 UTC 9:00, 즉 일본 시간 18:00에 실행됩니다. 처음에 말한 "오후 6시에 실행됐다"가 바로 이 경우입니다.

  • 일본 시간 → UTC: 시에서 9를 뺀다(9:00 → 0:00, 18:30 → 9:30)
  • 뺀 결과가 음수일 때(일본 시간 0~8시대)는 24를 더하고 "전날" 시각으로 본다(8:00 → 전날 23:00)
  • UTC → 일본 시간: 시에 9를 더한다. 24 이상이 되면 24를 빼고 "다음 날"로 본다
  • 일본에는 서머타임이 없어서 계절에 따라 시차가 바뀌지 않는다(항상 9시간)

일본 시간 → UTC cron 식 변환표

자주 쓰는 시각을 일본 시간 기준 cron 식과 GitHub Actions에 써야 할 UTC cron 식으로 나란히 정리했습니다. 오른쪽 열을 그대로 - cron:에 붙여 넣으면 왼쪽의 일본 시간에 실행됩니다(실제로는 뒤에서 설명하는 지연이 더해집니다).

실행하고 싶은 시각(일본 시간)일본 시간 기준 cron 식GitHub Actions에 쓸 식(UTC)
매일 9:000 9 * * *0 0 * * *
매일 8:3030 8 * * *30 23 * * *(전날 23:30)
매일 18:000 18 * * *0 9 * * *
매일 0:00(날짜가 바뀔 때)0 0 * * *0 15 * * *(전날 15:00)
평일(월~금) 9:000 9 * * 1-50 0 * * 1-5
평일(월~금) 8:000 8 * * 1-50 23 * * 0-4(일~목 23:00)
평일(월~금) 6:000 6 * * 1-50 21 * * 0-4(일~목 21:00)
평일 9~18시 매시 정각0 9-18 * * 1-50 0-9 * * 1-5
매주 월요일 0:000 0 * * 10 15 * * 0(일요일 15:00)
2시간마다(0·2·4…시)0 */2 * * *0 1-23/2 * * *
매월 15일 9:000 9 15 * *0 0 15 * *
매월 1일 3:000 3 1 * *한 줄로는 정확히 쓸 수 없음(뒤에서 설명)

표에서 주의할 것은 일본 시간 0~8시대를 지정한 행입니다. 시각을 9시간 되돌리면 전날이 되므로 시뿐 아니라 요일이나 날짜도 하나 되돌려야 합니다. "평일 8:00"을 시만 고쳐 "0 23 * * 1-5"로 쓰면 UTC 월~금 23:00, 즉 일본 시간 화~토 8:00에 실행되어 월요일 아침에는 돌지 않고 토요일 아침에 도는 어긋남이 생깁니다.

"2시간마다"도 놓치기 쉬운 예입니다. 일본 시간 0·2·4…22시는 UTC로 15·17·19·21·23·1·3…13시로 모두 홀수 시각이 되므로 "*/2"를 그대로 두면 1시간씩 어긋납니다. UTC의 홀수 시각을 뜻하는 "1-23/2"로 바꿔 써야 합니다.

오전 0~8시는 "전날·전 요일"이 된다: 밀림 계산법

일본 시간을 UTC로 바꿀 때 날짜가 바뀌는지는 "시"만으로 정해집니다. 일본 시간 9시 이후면 같은 날, 0~8시대면 전날이 됩니다. 요일·날짜 필드를 고치는 순서는 다음과 같습니다.

  1. 1

    시에서 9를 뺀다

    8:00이면 8 − 9 = −1. 음수가 되면 24를 더해 23으로 하고 "전날로 밀린다"는 것을 기억해 둡니다. 9 이상이면 뺀 값을 그대로 쓰고 날짜는 밀리지 않습니다.

  2. 2

    요일 필드를 하나 되돌린다

    전날로 밀리는 경우 요일 숫자에서 1을 뺍니다. 월~금(1-5)은 일~목(0-4)으로, 월요일(1)은 일요일(0)로, 일요일(0)은 토요일(6)이 됩니다. 요일이 *이면 고칠 필요가 없습니다.

  3. 3

    날짜 필드를 하나 되돌린다

    날짜로 지정했을 때도 똑같이 1을 뺍니다. 15일이면 14일입니다. 단, 1일을 되돌리면 "전월 말일"이 되는데 말일은 달마다 28~31일로 달라서 cron 한 줄로는 정확히 쓸 수 없습니다.

  4. 4

    다음 실행 일시로 확인한다

    고친 식의 다음 실행 일시를 일본 시간으로 10개 정도 나열해 원래 의도(월요일 아침 8시에 실행 등)와 맞는지 확인합니다. 암산 실수는 여기서 드러납니다.

시각이 하나뿐이면 암산으로도 되지만, 여러 시각·요일·날짜가 섞이면 갑자기 틀리기 쉬워집니다. cron 식 검사기의 "일본 시간과 UTC 변환"에 일본 시간 기준 식을 넣으면 요일·날짜 밀림까지 반영한 UTC 식을 보여 주고, 변환 전후의 다음 40회 실행 시각이 일치하는지 자동으로 대조합니다.

한 줄로 쓸 수 없으면 - cron:을 두 줄로 나눈다

일본 시간 "평일 7:00과 12:00"처럼 9시 이전과 이후 시각이 섞여 있으면 UTC로 바꿨을 때 7:00만 전날로 밀립니다. 전날로 밀리는 시각과 밀리지 않는 시각은 요일 필드가 달라서 하나의 cron 식으로 합칠 수 없습니다.

일본 시간UTC 시각요일 필드GitHub Actions에 쓸 식
평일 12:003:00(같은 날)1-5 그대로0 3 * * 1-5
평일 7:0022:00(전날)0-4로 되돌림0 22 * * 0-4

GitHub Actions의 on.schedule에는 cron을 여러 개 나열할 수 있으므로 이럴 때는 "- cron: '0 3 * * 1-5'"와 "- cron: '0 22 * * 0-4'" 두 줄로 나눠 씁니다. 어느 한쪽 시각에 해당하면 워크플로가 실행됩니다. 작업 안에서 어느 시각으로 실행됐는지 알고 싶다면, github.event.schedule에 그때 실행된 cron 식 문자열이 들어 있으므로 if 조건으로 분기할 수 있습니다.

schedule이 늦거나 실행되지 않을 때의 원인과 대책

시각을 UTC로 정확히 바꿔도 GitHub Actions의 schedule은 "지정한 시각 정각"에 실행되지 않을 수 있습니다. GitHub 문서에도 부하가 높은 시간대에는 지연될 수 있고, 혼잡할 때는 대기열의 작업이 버려질 수 있다고 나와 있습니다. 흔한 원인을 정리해 둡니다.

증상원인대책
매번 5~30분 정도 늦는다매시 0분에는 전 세계의 schedule이 몰린다분을 0이 아닌 값(예: 17분, 43분)으로 옮긴다
가끔 한 번이 통째로 실행되지 않는다혼잡할 때 대기열에서 빠질 수 있다놓쳐도 문제없는 처리로 만들고, 중요한 처리는 다른 방식도 검토한다
"*/1" "*/3"이어도 5분마다만 실행된다schedule의 최단 간격은 5분5분 미만 간격이 필요하면 다른 스케줄러를 쓴다
브랜치에 뒀는데 실행되지 않는다schedule은 기본 브랜치 최신 커밋의 파일만 대상main(기본 브랜치)에 병합한다
한동안 방치했더니 멈췄다공개 저장소는 60일간 활동이 없으면 schedule이 비활성화된다Actions 탭에서 워크플로를 다시 활성화한다
포크에서는 실행되지 않는다포크한 저장소는 Actions가 꺼져 있는 경우가 많다포크 쪽의 Actions를 켠다

특히 효과가 큰 것은 "분을 옮기는" 것입니다. 꼭 9:00 정각일 필요가 없다면 일본 시간 9:17에 해당하는 "17 0 * * *"처럼 쓰기만 해도 0분의 혼잡을 피해 지연이 눈에 띄게 줄어듭니다. 반대로 업무 시작 전에 반드시 끝나야 하는 처리는 지연을 감안해 30분~1시간 일찍 설정해 두면 안심입니다.

설정했다면 확인하기: 수동 실행과 다음 실행 일시 점검

schedule은 다음 시각이 올 때까지 제대로 동작하는지 알 수 없습니다. 매일·매주 실행하는 워크플로라면 실수를 알아차리기까지 며칠이 걸립니다. push 전후로 다음 세 가지를 확인해 두면 재작업이 줄어듭니다.

  • on:에 workflow_dispatch:도 추가해 Actions 탭에서 수동으로 실행하고, 작업 내용이 성공하는지 먼저 확인한다
  • cron 식 검사기에서 GitHub Actions를 고르고 식을 붙여 넣어 다음 실행 일시를 일본 시간으로 나열하고, 요일과 시각이 의도대로인지 본다
  • 첫 실행이 끝나면 실행 기록의 시각(UTC)에 9시간을 더해 예상한 일본 시간에 실행됐는지 대조한다

cron 식 자체의 작성법(5개 필드와 */5 같은 기호)이 헷갈린다면 crontab 작성법과 빠른 참조표에서 기본을 확인할 수 있습니다. "매월 둘째 월요일"이나 "월말"처럼 GitHub Actions의 cron만으로는 쓰기 어려운 지정은 cron의 날짜·요일 OR 규칙과 n번째 요일·월말 작성법에서 명령 쪽에서 날짜를 확인하는 방법을 소개합니다. AWS에서 같은 일을 한다면 EventBridge cron 식 작성법을 참고하세요.

자주 묻는 질문

GitHub Actions cron을 일본 시간 9시에 실행하려면?
GitHub Actions의 cron은 UTC로 해석되므로 일본 시간에서 9시간을 뺀 UTC 0:00을 지정합니다. 매일이면 "0 0 * * *", 평일만이면 "0 0 * * 1-5"입니다. 일본 시간 9시 이후는 날짜도 요일도 밀리지 않으므로 시에서 9를 빼기만 하면 됩니다.
GitHub Actions schedule의 시간대를 일본 시간으로 설정할 수 있나요?
cron 식은 UTC로 해석되므로 일본 시간을 UTC로 바꿔 쓰는 것이 기본입니다. 작업 안에서 쓰는 날짜와 시각만 일본 시간으로 하고 싶다면 스텝이나 작업의 환경 변수에 TZ: Asia/Tokyo를 설정합니다. 이것은 date 명령 등의 표시에만 영향을 주며 스케줄 시각은 바뀌지 않습니다.
일본 시간 오전 8시를 UTC로 바꾸면 요일은 어떻게 되나요?
일본 시간 8:00은 UTC 전날 23:00이므로 요일도 하나 되돌립니다. 평일(월~금) 8:00이면 UTC로 일~목 23:00이고 "0 23 * * 0-4"라고 씁니다. 시만 고쳐 "0 23 * * 1-5"로 하면 일본 시간 화~토 아침에 실행됩니다.
GitHub Actions schedule이 제시간에 실행되지 않는 이유는?
매시 0분에는 전 세계의 워크플로가 몰리기 때문에 몇 분에서 수십 분 늦거나, 혼잡할 때는 실행이 건너뛰어질 수 있습니다. 분 필드를 0이 아닌 값(17분 등)으로 옮기면 덜 늦습니다. 또한 schedule은 기본 브랜치의 파일만 대상이고, 공개 저장소는 60일간 업데이트가 없으면 비활성화된다는 점도 확인하세요.
GitHub Actions cron으로 1분마다 실행할 수 있나요?
할 수 없습니다. schedule로 실행할 수 있는 최단 간격은 5분입니다. "* * * * *"나 "*/1 * * * *"라고 써도 5분보다 짧은 간격으로는 실행되지 않습니다. 분 단위 모니터링 등이 필요하다면 외부 모니터링 서비스나 상시 가동 서버의 cron 같은 다른 방식을 사용합니다.

이 글에서 소개한 도구

함께 읽으면 좋은 글

사용 가이드약 10분

crontab 작성법과 빠른 참조표: 5개 필드와 기호의 의미, 자주 쓰는 예, 등록 명령

"매일 3시에 백업", "5분마다 모니터링 스크립트" 같은 정기 실행은 Linux에서는 crontab에 한 줄만 쓰면 설정할 수 있습니다. 하지만 "분 시 일 월 요일" 5개 필드와 * , - / 기호의 조합은 익숙해지기 전까지 잘못 읽기 쉬워서, 1시간에 60번 실행되거나 7분마다 돌리려던 것이 4분 간격이 되는 사고도 자주 일어납니다. 이 글에서는 crontab 작성법의 기본과 기호의 의미, 그대로 쓸 수 있는 빠른 참조표, crontab -e·-l·-r 사용법, 명령 부분을 쓸 때의 주의점을 예시 중심으로 설명합니다.

글 읽기 →
원리 해설약 10분

cron의 날짜와 요일은 OR: 둘째 월요일·월말·마지막 금요일·격주를 올바르게 쓰는 법

"매월 첫째 월요일 9시"라는 생각으로 "0 9 1-7 * 1"이라고 썼더니 매주 월요일에 더해 매월 1~7일 매일에도 실행됐다. cron에서 아주 흔한 이 실수는 날짜와 요일을 둘 다 지정하면 "둘 중 하나"에 해당하는 날에 실행된다는 cron 특유의 규칙 때문입니다. 이 글에서는 날짜와 요일이 OR이 되는 원리와 예외, crontab에서 n번째 요일·월말·마지막 금요일·격주를 올바르게 실행하는 방법, AWS EventBridge와 Spring에서 쓸 수 있는 L·#·W 표기까지 실제 실행 날짜 예시와 함께 설명합니다.

글 읽기 →
사용 가이드약 10분

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와의 변환표까지 정리합니다.

글 읽기 →