topic★★★★★난이도 · 약 20분
시간 · 타임존 · UTC · UNIX epoch
서버는 UTC, 사용자는 KST — 변환 규칙만 지키면 끝. "하루 어긋남" 사고의 교과서.
#UTC#epoch#타임존#KST#ISO8601#Intl
왜 배우는가
시간 버그는 AI도 자주 틀린다. "어제 가입"이 "오늘"로 표시, "오전 9시 예약"이 다른 타임존에서 "밤 11시"로. 서버 UTC / 표시만 로컬 변환 규칙만 고수하면 90%가 해결.
UTC(Coordinated Universal Time)는 전 세계 표준 시계. 한국(KST)은 UTC+9. UNIX epoch는 `1970-01-01 00:00:00 UTC`부터의 초(또는 밀리초). `Date.now()` = 밀리초 epoch.
| 형식 | 예시 | 용도 |
|---|---|---|
| UNIX epoch (초) | `1700000000` | DB·API 저장 |
| UNIX epoch (ms) | `1700000000000` | JS `Date.now()` |
| ISO 8601 | `2023-11-14T22:13:20Z` | API·로그 권장 |
| ISO + 타임존 | `...+09:00` | 오프셋 명시 |
| 사람 표시 | `2023.11.15 07:13 KST` | UI만 |
javascript
// 황금률: 서버·DB는 UTC, 표시할 때만 사용자 타임존으로
// ❌ 위험: 로컬 시간 문자열로 저장
const now = new Date().toString();
// "Tue Nov 14 2023 22:13:20 GMT+0900 (KST)"
// → DB마다 서버 TZ 다르면 지옥
// ✅ ISO/UTC로 저장
new Date().toISOString() // "2023-11-14T13:13:20.000Z" (Z=UTC)
Date.now() // 1700000000000 (ms epoch)
// 표시할 때만 타임존 변환
new Intl.DateTimeFormat("ko-KR", {
timeZone: "Asia/Seoul",
dateStyle: "full",
timeStyle: "short",
}).format(new Date(iso)); // "2023년 11월 14일 화요일 오후 10:13"
// 라이브러리 선택 (2026년 기준)
// - date-fns : 함수형, 트리셰이킹 좋음
// - Day.js : moment 후계자, 경량
// - Temporal API : 내장 표준 (Stage 3, 곧 기본)
// ⚠️ moment.js는 유지보수 중단, 신규 코드에 쓰지 말 것Claude에게 "시간은 UTC로 저장, Intl로 KST 표시"를 명시하면 깔끔한 코드가 나온다.
3대 함정. ① `new Date("2023-11-14")` → 타임존 모호(ISO 날짜만은 UTC로 해석됨, KST 가정 안 됨). ② DST(서머타임) — 한국은 없지만 미국·유럽은 있음. 한 시간이 사라지거나 두 번 오는 날 존재. ③ 윤초(leap second) — 드물지만 실존.
javascript
// "오늘 자정부터 내일 자정까지의 주문" 쿼리 (KST 기준)
import { startOfDay, endOfDay } from "date-fns";
import { toZonedTime, fromZonedTime } from "date-fns-tz";
const tz = "Asia/Seoul";
const now = new Date();
const kstStart = fromZonedTime(startOfDay(toZonedTime(now, tz)), tz);
const kstEnd = fromZonedTime(endOfDay(toZonedTime(now, tz)), tz);
// SQL에 UTC 그대로 넘기면 됨
// WHERE created_at >= $1 AND created_at < $2"KST 오늘"을 UTC 구간으로 변환 → DB는 UTC라서 그냥 비교하면 됨. 이 패턴 하나면 날짜 버그가 거의 사라진다.
실기 드릴 2문항
edit실기 드릴 · 단답형
`1970-01-01 00:00:00 UTC`를 기준으로 경과 초를 세는 시간 표현 방식은?
check_circle실기 드릴 · OX
서버 저장도 사용자 타임존으로 저장하는 게 정석이다.