diff --git a/ideas/UTC_aware_datetime_handling_strategy.md b/ideas/UTC_aware_datetime_handling_strategy.md new file mode 100644 index 0000000..b8e6e7c --- /dev/null +++ b/ideas/UTC_aware_datetime_handling_strategy.md @@ -0,0 +1,59 @@ +# UTC Aware DateTime 처리 전략 + +## 작성일: 2025-08-28 +## 작성자: 서버 관리자 +## 카테고리: 아이디어/베스트 프랙티스 + +--- + +## 배경 +- Gmail 토큰 만료 체크 시 `can't subtract offset-naive and offset-aware datetimes` 오류 발생 +- 타임존 혼용으로 인한 반복적인 버그 발생 (250819, 250828 사례) + +## 핵심 전략: 내부 UTC, 외부 KST + +### 1. 저장 및 처리 (UTC) +```python +# 모든 DB 저장은 UTC +expires_at = datetime.now(timezone.utc) + timedelta(hours=1) + +# 비교도 UTC로 통일 +if datetime.now(timezone.utc) > expires_at: + refresh_token() +``` + +### 2. 한국 시간 이벤트 처리 +```python +from zoneinfo import ZoneInfo + +def is_kst_hour(hour: int) -> bool: + """KST 특정 시간 체크 (예: 9시 브리핑)""" + return datetime.now(ZoneInfo("Asia/Seoul")).hour == hour + +def kst_to_utc(kst_hour: int) -> datetime: + """KST 시간을 UTC로 변환""" + kst_now = datetime.now(ZoneInfo("Asia/Seoul")) + kst_target = kst_now.replace(hour=kst_hour, minute=0, second=0) + return kst_target.astimezone(timezone.utc) +``` + +### 3. 범용 변환 함수 +```python +def to_utc_aware(dt_str: str) -> datetime: + """모든 datetime 문자열을 UTC aware로 통일""" + if not dt_str: + return None + dt = datetime.fromisoformat(dt_str.replace('Z', '+00:00')) + return dt.replace(tzinfo=timezone.utc) if dt.tzinfo is None else dt +``` + +## 적용 원칙 +1. **DB Schema**: TIMESTAMP WITH TIME ZONE 사용 권장 +2. **API Response**: ISO 8601 with Z suffix (예: `2025-08-28T00:00:00Z`) +3. **Cron Jobs**: 서버 타임존(KST) 기준, 코드에서 UTC 변환 +4. **Frontend Display**: 사용자 로컬 시간으로 표시 + +## 기대 효과 +- ✅ naive/aware datetime 충돌 완전 방지 +- ✅ 글로벌 서비스 확장 시 타임존 이슈 없음 +- ✅ 코드 일관성 및 유지보수성 향상 \ No newline at end of file