핵심 문제
크론은 UTC가 아닌 벽시계 시간을 사용합니다. 서버가 현지 시간대로 설정되어 있고 DST가 발생하면, 0 2 * * *(매일 오전 2시)로 예약된 크론 잡이:
- 시계가 뒤로 돌아갈 때 두 번 실행될 수 있습니다 (오전 2시가 두 번 발생)
- 시계가 앞으로 당겨질 때 실행되지 않을 수 있습니다 (오전 2시가 건너뜀)
- 여름과 겨울에 1시간 드리프트가 생길 수 있습니다
안전한 해결책: 서버를 UTC로 설정
가장 간단한 해결책: 서버 시스템 시간대를 UTC로 설정하세요. 그러면 크론은 항상 UTC를 사용하고 DST는 무관합니다:
# 현재 시간대 확인
timedatectl
# UTC로 설정
sudo timedatectl set-timezone UTC
명시적 시간대 크론 (GNU cron)
CRON_TZ=America/New_York
# 뉴욕 시간 오전 9시 평일
0 9 * * 1-5 /usr/local/bin/send-morning-report.sh
CRON_TZ=Asia/Seoul
# 서울 자정
0 0 * * * /usr/local/bin/daily-backup.sh
현대적 스케줄러: 더 나은 시간대 지원
# GitHub Actions — 항상 UTC
on:
schedule:
- cron: "0 9 * * 1-5" # UTC 오전 9시 = KST 오후 6시
# AWS EventBridge — UTC 전용
# "cron(0 9 ? * MON-FRI *)"
DST 안전 "업무 시간" 스케줄링
사용자의 "오전 9시 업무 시간"에 보고서를 보내야 한다면, UTC-5를 하드코딩하지 마세요. 비즈니스 규칙을 시간대 이름으로 저장하고 매일 UTC 해당값을 계산하세요:
from zoneinfo import ZoneInfo
from datetime import datetime, time, timezone
def next_9am_utc(iana_tz: str) -> datetime:
tz = ZoneInfo(iana_tz)
today = datetime.now(tz).date()
local_9am = datetime.combine(today, time(9, 0), tzinfo=tz)
return local_9am.astimezone(timezone.utc)