JavaScript 시간대 처리: Intl과 Luxon

JavaScript Date 객체의 시간대 문제

JavaScript의 Date 객체는 내부적으로 항상 UTC 타임스탬프로 저장하지만, 대부분의 메서드는 브라우저의 현지 시간대 값을 반환합니다. 이 불일치가 특히 서로 다른 환경에서 실행될 때 많은 미묘한 버그를 유발합니다.

const d = new Date("2024-03-01T14:00:00Z");
console.log(d.getHours());        // 현지 시간 — 브라우저 위치마다 다름!
console.log(d.getUTCHours());     // 14 — 항상 UTC, 예측 가능

Intl API 사용하기 (라이브러리 불필요)

현대적인 Intl.DateTimeFormat API를 사용하면 외부 의존성 없이 어떤 시간대로도 날짜를 포맷할 수 있습니다:

const d = new Date("2024-03-01T14:00:00Z");

// 서울 시간으로 포맷
const seoulFormatter = new Intl.DateTimeFormat("ko-KR", {
  timeZone: "Asia/Seoul",
  dateStyle: "full",
  timeStyle: "short",
});
console.log(seoulFormatter.format(d));
// 2024년 3월 1일 금요일 오후 11:00

Luxon: 현대적 날짜 라이브러리

Luxon은 Moment.js의 후계자로, 불변성과 Intl API 기반 시간대 지원을 중심으로 설계되었습니다:

import { DateTime } from "luxon";

const dt = DateTime.fromISO("2024-03-01T14:00:00Z");
const seoul = dt.setZone("Asia/Seoul");
console.log(seoul.toString());
// 2024-03-01T23:00:00.000+09:00

console.log(seoul.toFormat("yyyy-MM-dd HH:mm z"));
// 2024-03-01 23:00 KST

모범 사례

  • API에서 날짜를 UTC ISO 문자열로 파싱하세요: new Date("2024-03-01T14:00:00Z")
  • Node.js 서버에서는 get* 대신 getUTC* 메서드를 사용하세요
  • 복잡한 시간대 로직에는 Luxon 또는 date-fns-tz를 사용하세요
  • 시간 없이 new Date("2024-03-01")을 사용하지 마세요 — UTC 자정으로 파싱되어 서쪽 시간대에서 전날로 표시될 수 있습니다