feat(time): 프로젝트 전체 시간 KST(UTC+9) 통일

- app/timezone.py 신설: KST 고정오프셋(+9, DST 없음) + now_kst/today_kst/to_kst_iso
- DB 직렬화 created_at/updated_at/decided_at/uploaded_at 표시를 UTC→KST 로 변환
  (expense/cupang/vacation db.py)
- _now_iso(JSON 저장) KST 기준
- 라우터 date.today()/datetime.now() → today_kst()/now_kst() (달력 '오늘'/엑셀 파일명)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-30 08:48:28 +09:00
parent 32fc12e283
commit fa1027fa1b
9 changed files with 80 additions and 30 deletions
+5 -4
View File
@@ -13,10 +13,11 @@ import mimetypes
import os
import re
import uuid
from datetime import datetime
from pathlib import Path
from typing import Any
from app.timezone import now_kst
from fastapi import (
APIRouter,
Depends,
@@ -231,11 +232,11 @@ async def reports_page(request: Request) -> HTMLResponse:
return RedirectResponse(url="/login", status_code=303)
store = _store(request)
_require_db_store(store)
year_str = request.query_params.get("year") or str(datetime.now().year)
year_str = request.query_params.get("year") or str(now_kst().year)
try:
year = int(year_str)
except ValueError:
year = datetime.now().year
year = now_kst().year
rows = store.monthly_summary(email=user["email"], year=year)
# 피벗: month → {category → total}
@@ -633,7 +634,7 @@ async def export_xlsx(
buf.seek(0)
fname_scope = "all" if target_email is None else "mine"
fname = f"expense_{fname_scope}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
fname = f"expense_{fname_scope}_{now_kst().strftime('%Y%m%d_%H%M%S')}.xlsx"
return StreamingResponse(
buf,
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",