황금 원칙: 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를 의미합니다.