JavaScript Temporal API 정리
JavaScript에서 사용하던 기존 Date 객체는 JavaScript의 등장과 함께 만들어졌지만,
오랜 시간 동안 여러 설계 결함으로 인해 개발자들을 힘들게 했습니다.
Temporal API는 기존 Date를 대체하기 위해 등장한
불변(immutable) 기반의 현대적인 날짜/시간 API입니다.
기존
Date는 개발 당시 Java의java.util.Date를 참고해 만들어졌습니다. 하지만 Java는 이후 해당 설계 문제를 개선하기 위해java.time으로 변경했습니다.
1. Date의 문제점
기존 Date 객체는 JavaScript의 큰 실수 중 하나라고 불릴 만큼 여러 결함이 있습니다.
-
가변성:
date.setMonth(2)를 호출하면 원본 객체 자체가 변경됩니다. 이로 인해 예측하기 어려운 버그가 발생할 수 있습니다. -
0부터 시작하는 월: 1월은
0, 12월은11입니다. 반면 일(day)은 1부터 시작합니다. -
타임존 지원 부족: 기본적으로 로컬 시간과 UTC만 다루기 쉬우며,
Asia/Seoul같은 특정 지역 타임존 처리가 어렵습니다. -
신뢰하기 어려운 파싱: 문자열 형식에 따라 브라우저별 결과가 달라질 수 있습니다. 예를 들어 Safari에서는 특정 날짜 문자열이
Invalid Date가 될 수 있습니다. -
산술 연산 부재: 2일 뒤 날짜를 구하려면
setDate(getDate() + 2)같은 방식으로 직접 처리해야 합니다.
Date의 가변성 예시
const date = new Date('2026-01-31');
date.setMonth(1);
console.log(date.getMonth()); // 2로 변경될 수 있음
위 예시는 날짜 보정 과정에서 예상과 다른 월이 나올 수 있음을 보여줍니다.
기존 Date는 원본 객체를 직접 변경하기 때문에 이런 문제가 더 위험해집니다.
2. Temporal API의 특징
Temporal API는 기존 Date의 단점을 해결하기 위해 다음과 같은 특징을 제공합니다.
-
불변성: 모든 연산은 새로운 객체를 반환하며, 원본 객체를 변경하지 않습니다.
-
직관적인 인덱싱: 1월은
1, 12월은12입니다. -
명확한 타입 분리: 날짜, 시간, 타임존, 기간에 대해 전용 타입을 제공합니다.
-
나노초 정밀도: 밀리초를 넘어 나노초 단위의 정밀한 시간 계산이 가능합니다.
특히 결제 시스템, 로그 기록, 국제 서비스처럼 정확한 시간 처리가 필요한 환경에서 유용합니다.
3. 주요 데이터 타입
Temporal API는 용도에 따라 날짜와 시간 타입을 세분화합니다.
| 타입 | 설명 | 용도 | 예시 |
|---|---|---|---|
Temporal.Instant |
UTC 기준의 특정 시점 | 로그 기록, 타임스탬프 | 2026-04-17T07:01:53.833070068Z |
Temporal.ZonedDateTime |
타임존 + 날짜 + 시간 | 국제 타임스탬프 | 2026-04-17T16:02:31.748465088+09:00[Asia/Seoul] |
Temporal.PlainDate |
타임존 없는 날짜 | 생일, 기념일, 달력 | 2026-04-17 |
Temporal.PlainTime |
타임존 없는 시간 | 시간표, 일과표 | 16:03:29.30323999 |
Temporal.PlainDateTime |
타임존 없는 날짜 + 시간 | 타임존이 중요하지 않은 시간 기록 | 2026-04-17T16:04:02.764425049 |
Temporal.Duration |
시간의 간격 | 시간 차이 계산 | PT77H |
4. 실제 사용법
4-1. 현재 시간 가져오기
// 현재 시점 UTC
const now = Temporal.Now.instant();
console.log(now.toString());
// "2026-04-17T07:09:26.658169922Z"
// 특정 타임존의 현재 날짜와 시간
const seoulNow = Temporal.Now.zonedDateTimeISO('Asia/Seoul');
console.log(seoulNow.toString());
// "2026-04-17T16:09:38.859280029+09:00[Asia/Seoul]"
4-2. 날짜 생성 및 지정
const date = Temporal.PlainDate.from({
year: 2026,
month: 4,
day: 17
});
console.log(date.month); // 4
const date = Temporal.PlainDate.from('2026-04-17');
console.log(date.month); // 4
4-3. 날짜 연산
Temporal에서는 add, subtract, until, since 같은 메서드로
날짜 계산을 더 직관적으로 처리할 수 있습니다.
또한 compare, equals를 사용해 날짜 비교도 가능합니다.
compare()결과가-1이면 앞의 날짜가 더 이전입니다.compare()결과가0이면 두 날짜가 같습니다.compare()결과가1이면 앞의 날짜가 더 이후입니다.
const today = Temporal.Now.plainDateISO();
const nextWeek = today.add({ days: 7 });
const lastMonth = today.subtract({ months: 1 });
console.log(today.toString());
console.log(nextWeek.toString());
console.log(lastMonth.toString());
const isBefore = Temporal.PlainDate.compare(today, nextWeek) === -1;
console.log(isBefore); // true
4-4. 두 시점 사이의 차이 구하기
until과 since를 사용하면 두 날짜 사이의 차이를 쉽게 계산할 수 있습니다.
start.until(end): start에서 end까지 얼마나 남았는지 계산합니다.end.since(start): end 기준으로 start 이후 얼마나 지났는지 계산합니다.largestUnit: 결과를 어떤 단위부터 묶을지 결정합니다.
const start = Temporal.PlainDate.from('2025-01-01');
const end = Temporal.PlainDate.from('2026-05-20');
const diffYear = start.until(end, { largestUnit: 'year' });
console.log(diffYear.years); // 1
console.log(diffYear.months); // 4
console.log(diffYear.days); // 19
const diffMonth = start.until(end, { largestUnit: 'month' });
console.log(diffMonth.years); // 0
console.log(diffMonth.months); // 16
console.log(diffMonth.days); // 19
const diffDay = start.until(end, { largestUnit: 'day' });
console.log(diffDay.years); // 0
console.log(diffDay.months); // 0
console.log(diffDay.days); // 504
4-5. 특정 필드 변경
with 메서드를 사용하면 특정 필드만 변경한 새로운 객체를 만들 수 있습니다.
Temporal 객체는 불변이므로 원본 객체는 변경되지 않습니다.
const date = Temporal.PlainDate.from('2026-04-17');
const changedDate = date.with({ year: 2025 });
console.log(date.toString()); // "2026-04-17"
console.log(changedDate.toString()); // "2025-04-17"
5. 브라우저 지원
Temporal API는 TC39 프로세스를 거쳐 표준화가 진행된 최신 날짜/시간 API입니다.
다만 아직 모든 브라우저에서 안정적으로 사용할 수 있는 것은 아니므로, 실제 서비스에 도입하기 전에는 브라우저 지원 현황을 반드시 확인해야 합니다.
특히 Safari 등 일부 환경에서는 아직 정식 지원이 부족할 수 있어, 적극적으로 도입하기에는 주의가 필요합니다.
6. 폴리필 사용
Temporal API를 아직 지원하지 않는 환경에서도 사용하고 싶다면 폴리필을 설치해 사용할 수 있습니다.
TC39 제안 챔피언이 관리하는 공식 폴리필도 있고,
경량 폴리필인 temporal-polyfill도 많이 사용됩니다.
사용법은 네이티브 Temporal API와 거의 동일합니다.
npm install temporal-polyfill
패키지 링크: temporal-polyfill
정리
기존
Date는 가변성, 불명확한 월 인덱스, 부족한 타임존 처리 등 여러 문제가 있습니다.Temporal은 불변성을 기반으로 날짜와 시간을 더 안전하게 다룰 수 있게 해줍니다.날짜, 시간, 타임존, 기간을 명확한 타입으로 분리합니다.
나노초 단위의 정밀한 시간 계산을 지원합니다.
아직 브라우저 지원 상태를 확인해야 하며, 필요하다면 폴리필을 사용할 수 있습니다.

댓글 0