BioPlayground

🧬
목록으로

Date & Temporal API — JS에서 가장 이상한 문법

JavaScript Date 객체의 대표적인 함정들과 이를 해결하려는 Temporal API의 등장 배경을 설명합니다.

중급
|
5
|
검증 완료 (2026-07)
진행률0/36 (0%)

Date & Temporal API — JS에서 가장 이상한 문법

이 토픽을 마치면

JavaScript Date 객체의 대표적인 함정을 알게 되고, Temporal API가 왜 필요한지 이해하게 됩니다.


1월이 0입니다

JavaScript에서 날짜를 만들어 봅시다:

javascript
const date = new Date(2026, 6, 7);
console.log(date);
// Tue Jul 07 2026 ...

7월 7일을 만들려면 월에 6을 넣어야 합니다. JavaScript의 월은 0부터 시작하기 때문입니다. 1월 = 0, 2월 = 1, ..., 12월 = 11.

이건 1995년 JavaScript가 Java의 Date 클래스를 그대로 베끼면서 생긴 문제입니다. Java는 이후에 고쳤지만, JavaScript는 호환성 때문에 27년째 못 고치고 있습니다.


더 많은 함정들

월이 0인 것만이 아닙니다:

javascript
new Date("2026-07-07");
// UTC 기준 → 한국에서 실행하면 07월 07일 09:00 (KST)

new Date("07/07/2026");
// 로컬 시간대 기준 → 07월 07일 00:00 (KST)

같은 날짜인데 문자열 포맷에 따라 시간대 해석이 달라집니다. 하이픈(-)이면 UTC, 슬래시(/)면 로컬. 이걸 의도한 사람은 아무도 없습니다.

날짜 비교도 직관적이지 않습니다:

javascript
const a = new Date("2026-07-07");
const b = new Date("2026-07-07");
console.log(a === b);  // false
console.log(a == b);   // false

Date는 객체라서 참조 비교가 됩니다. 비교하려면 a.getTime() === b.getTime()으로 밀리초 값을 꺼내야 합니다.

그리고 Date 객체는 불변이 아닙니다:

javascript
const date = new Date("2026-07-07");
date.setMonth(11);
// date가 12월로 바뀜 — 원본이 변경됨

함수에 Date를 넘겼는데 그 함수가 setMonth를 호출하면 내 원본 날짜가 바뀝니다.


그래서 라이브러리를 씁니다

Date의 함정이 너무 많아서 실무에서는 거의 항상 라이브러리를 씁니다.

moment.js — 한때 표준이었지만 번들 크기가 크고(72KB), 가변 객체라 같은 문제를 반복합니다. 2020년에 공식적으로 "더 이상 새 프로젝트에 쓰지 마세요"라고 선언했습니다.

day.js — moment.js의 대안으로 등장. 같은 API인데 2KB입니다. 불변 객체라 원본이 안 바뀝니다. 현재 가장 많이 쓰이는 날짜 라이브러리입니다.

javascript
import dayjs from "dayjs";

dayjs("2026-07-07").add(1, "month").format("YYYY-MM-DD");
// "2026-08-07"

date-fns — 함수형 접근. 필요한 함수만 import해서 쓸 수 있어 tree-shaking에 유리합니다.


Temporal API: 근본적 해결

라이브러리는 땜질입니다. JavaScript 언어 자체에서 제대로 된 날짜/시간 API를 제공해야 합니다. 그게 Temporal API입니다.

javascript
const date = Temporal.PlainDate.from("2026-07-07");
date.month;      // 7 (0이 아님!)
date.dayOfWeek;  // 2 (화요일)

const next = date.add({ months: 1 });
// date는 그대로, next만 8월 7일 — 불변!

Temporal은 처음부터 다시 설계됐습니다:

월이 1부터 시작합니다. 1월 = 1, 12월 = 12. 인간의 상식과 일치합니다.

불변입니다. .add(), .subtract() 같은 메서드가 새 객체를 반환합니다. 원본은 절대 안 바뀝니다.

시간대를 명시적으로 다룹니다. PlainDate(날짜만), PlainTime(시간만), ZonedDateTime(시간대 포함)으로 구분됩니다. 시간대 때문에 버그가 나는 걸 구조적으로 방지합니다.

javascript
const meeting = Temporal.ZonedDateTime.from({
  timeZone: "Asia/Seoul",
  year: 2026,
  month: 7,
  day: 7,
  hour: 14,
  minute: 0,
});

meeting.withTimeZone("America/New_York").toString();
// 뉴욕 시간으로 자동 변환

지금 쓸 수 있나

Temporal API는 TC39 Stage 3 제안입니다. 브라우저에 완전히 탑재되기까지 시간이 필요합니다. 폴리필(@js-temporal/polyfill)을 쓰면 지금도 사용할 수 있지만, 프로덕션에서는 아직 day.js가 현실적인 선택입니다.

하지만 Temporal이 정식 채택되면 날짜 라이브러리 없이도 JavaScript만으로 날짜/시간을 안전하게 다룰 수 있게 됩니다.


핵심

JavaScript Date는 월이 0부터 시작하고, 가변이고, 시간대 해석이 일관적이지 않은 문제가 있습니다. 실무에서는 day.js 같은 라이브러리로 우회하고 있습니다. Temporal API는 이 문제를 언어 차원에서 근본적으로 해결하려는 차세대 표준입니다.