프로그래밍에서의 UTC 모범 사례

황금 원칙: UTC로 저장, 현지 시간으로 표시

시간 프로그래밍에서 가장 중요한 규칙은 간단합니다: 항상 UTC로 저장하고, 사용자에게 보여줄 때만 현지 시간대로 변환하세요. 이 하나의 원칙이 소프트웨어에서 발생하는 대부분의 시간대 관련 버그를 예방합니다.

UTC를 사용해야 하는 이유

  • 모호함 없음: UTC에는 일광절약시간제, 정치적 변경, 오프셋이 없습니다. UTC 타임스탬프는 항상 동일한 순간을 의미합니다.
  • 비교 가능: 두 UTC 타임스탬프는 변환 없이 비교하고 정렬할 수 있습니다.
  • 이식성: 데이터베이스, 서버 로그, API가 배포 위치와 무관하게 모두 UTC로 일치합니다.
  • 미래 안전성: 정부가 시간대 규칙을 바꿔도 UTC로 저장된 기록은 정확하게 유지됩니다.

흔한 실수

# 나쁜 예: 현지 시간 저장
created_at = datetime.now()          # naive datetime — 시간대 불명!

# 좋은 예: UTC 저장
from datetime import datetime, timezone
created_at = datetime.now(tz=timezone.utc)  # 시간대 인식 UTC

# 나쁜 예: 저장 전에 현지 시간으로 변환
user_time = datetime(2024, 3, 1, 14, 0, tzinfo=some_local_tz)
db.save(user_time)  # 현지 시간 저장 — 위험!

데이터베이스 설정

# PostgreSQL
SET timezone = 'UTC';

# MySQL
SET time_zone = '+00:00';

# Django settings
USE_TZ = True
TIME_ZONE = 'UTC'

API 설계: 항상 시간대 정보 포함

# 나쁜 예
{"created_at": "2024-03-01 14:00:00"}

# 좋은 예 — ISO 8601 + UTC 오프셋
{"created_at": "2024-03-01T14:00:00Z"}
{"created_at": "2024-03-01T14:00:00+00:00"}

사용자에게 현지 시간 표시하기

# Python — 표시 시점에 변환
from zoneinfo import ZoneInfo
utc_dt = datetime(2024, 3, 1, 14, 0, tzinfo=timezone.utc)
seoul_dt = utc_dt.astimezone(ZoneInfo("Asia/Seoul"))
print(seoul_dt)  # 2024-03-01 23:00:00+09:00

# JavaScript
new Date("2024-03-01T14:00:00Z").toLocaleString("ko-KR", {
  timeZone: "Asia/Seoul"
})

로깅

항상 UTC로 로그를 기록하세요. 로그 파일에 여러 시간대가 섞이면 여러 지역에 걸친 서버 디버깅이 매우 어려워집니다. 시간대 지시자를 명시적으로 포함하세요: 2024-03-01T14:00:00Z — 끝의 Z는 UTC를 의미합니다.