크론 잡과 시간대: 스케줄링 함정

핵심 문제

크론은 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)

관련 용어