수십 년간 이어진 Date 버그가 당신의 잘못이 아니었던 이유
수십 년 동안 JavaScript 개발자들은 실력 부족이 아니라 근본적인 설계 결함 때문에 네이티브 Date 객체와 씨름해 왔습니다. 가변성(mutability)으로 인해 Date를 전달하면 원본이 예기치 않게 변경되어 추적하기 어려운 부작용과 예상치 못한 동작이 발생하곤 했습니다. 또한 월(month)이 0부터 시작(1월은 0, 12월은 11)하는 직관적이지 않은 시스템은 숙련된 프로그래머조차 당황하게 만드는 오프바이원(off-by-one) 오류를 지속적으로 유발했습니다.
더욱 어려운 점은 Date가 사용자의 로컬 시스템 시간대에 의존한다는 것이었습니다. 이는 글로벌 애플리케이션에 지뢰밭과 같았는데, 특히 일광 절약 시간제(DST) 전환 시 '오전 9시' 이벤트가 지역에 따라 예측할 수 없이 몇 시간 또는 며칠씩 이동할 수 있었기 때문입니다. 이러한 암묵적인 가정들로 인해 외부 라이브러리 도움 없이는 서로 다른 위치 간의 일관된 시간을 계산하거나 고정된 시점을 저장하는 것이 거의 불가능했습니다.
이러한 복잡성에 직면한 개발자들은 Moment.js나 Luxon과 같은 외부 '임시 방편 라이브러리(band-aid libraries)'의 방대한 생태계를 채택했습니다. 이러한 도구들은 더 강력한 날짜 및 시간 조작 기능을 제공하며 꼭 필요한 구원책이 되었습니다. 하지만 번들 크기 증가, 복잡한 의존성 관리, 추가적인 추상화라는 자체적인 오버헤드를 초래했습니다. 이는 개발자의 역량이 아닌 네이티브 Date 객체의 부적절함을 반영하며 수년간 표준처럼 자리 잡았습니다.
타임스탬프가 아닌, 시간으로 사고하기
Temporal은 서로 다른 개념에 대해 서로 다른 불변(immutable) 객체를 사용한다는 근본적인 설계 철학을 도입하여 JavaScript의 날짜 문제를 해결합니다. 이러한 접근 방식은 명확성을 강제하여, 모든 것을 한꺼번에 처리하려던 기존 Date 객체에서 발생하던 조용한 부작용과 혼란을 방지합니다. 이제 함수가 예기치 않게 날짜를 수정했는지 고민할 필요가 없습니다.
Temporal은 단일하고 과부하된 객체 대신, 시간의 특정 측면을 처리하는 전문화된 타입을 제공합니다. 이러한 명확한 구분은 설계 단계부터 오류를 방지하며, 상황에 맞는 올바른 도구를 사용할 수 있게 합니다:
- Temporal.PlainDate: 시간이나 시간대 없이 달력 날짜만 나타냅니다.
- Temporal.PlainTime: 날짜와 무관하게 시계 시간만을 포착합니다.
- Temporal.Instant: Unix 에포크 이후의 나노초 단위로 측정되는 보편적이고 명확한 시점입니다.
- Temporal.ZonedDateTime: 특정 시간대에 고정된 완전한 날짜와 시간으로, 일광 절약 시간제와 같은 복잡성을 완전히 이해합니다.
또한, Temporal.Duration은 날짜 연산을 혁신합니다. 오류가 발생하기 쉬운 수동 밀리초 계산을 사람이 읽기 쉬운 연산으로 대체하여 date.add({ months: 2, days: 10 })와 같이 기간을 유연하게 더하거나 뺄 수 있게 합니다. 이러한 정밀함과 가독성은 일광 절약 시간 전환을 포함하는 복잡한 시간 계산을 놀라울 정도로 간단하고 신뢰할 수 있게 만듭니다.
Temporal이 일광 절약 시간을 정복하는 방법
10월 24일 토요일 오후 8시(뉴욕 시간)에 출발하여 7시간이 소요되는 뉴욕발 런던행 비행기를 상상해 보세요. 단순 계산으로는 뉴욕 시간으로 오전 3시(런던 시간으로 오전 8시, 5시간 시차 고려)에 도착할 것으로 보입니다. 하지만 그날 밤 런던은 일광 절약 시간제로 인해 시계가 한 시간 뒤로 조정됩니다.
기존의 단순한 날짜 계산 방식으로는 잘못된 오전 8시 도착 결과가 나옵니다. Temporal.ZonedDateTime은 이 중요한 세부 사항을 이해하여 올바른 도착 시간인 오전 7시를 자동으로 계산합니다. 특정 지리적 영역의 시간을 정확하게 모델링하여 까다로운 시간 전환에 대한 추측을 제거합니다.
Temporal은 내부적으로 IANA time zone database를 활용하여 이러한 정밀도를 달성합니다. 운영 체제와 서버에서도 사용하는 이 세계적으로 인정받는 데이터베이스는 모든 시간대와 과거 및 미래의 DST 변경 사항에 대한 정확하고 최신 정보를 제공합니다. 이는 개발자가 복잡한 시간대 규칙을 직접 관리할 필요가 없도록 하는 강력한 솔루션입니다. Temporal의 기능에 대한 자세한 내용은 Temporal - JavaScript - MDN Web Docs를 참조하세요.
Temporal은 강력한 검사 도구도 제공합니다. 개발자는 getTimeZoneTransition을 사용하여 일광 절약 시간(Daylight Saving Time) 변경 시점을 명시적으로 쿼리할 수 있으며, 이를 통해 로직에 대한 완전한 투명성을 확보할 수 있습니다. 이 기능은 복잡한 시간 기반 시나리오의 디버깅을 훨씬 더 쉽게 만들어 줍니다.
이 글이 마음에 드셨나요? 매일 아침 이런 글을 메일로 받아보세요.
하루 한 통 · 두 번의 클릭으로 구독 취소 · 제3자 추적 없음
지금 바로 Temporal 사용을 시작할 수 있습니다
Temporal은 더 이상 먼 미래의 이야기가 아닙니다. 개발자가 바로 사용할 수 있는 안정적이고 완성된 기능입니다. Temporal은 성숙도의 최고 단계인 TC39 Stage 4 상태에 도달했으며, 이는 ECMAScript 표준 포함을 위한 완성 및 준비가 완료되었음을 의미합니다. 개발자들은 Temporal이 ECMAScript 2027의 일부로 공식 출시될 것으로 기대할 수 있으며, 이는 그 견고한 설계와 폭넓은 합의를 입증합니다. 즉, 미래를 대비한 API를 도입하는 것입니다.
Temporal에 대한 기본 지원은 이미 주요 브라우저와 런타임 전반에 걸쳐 널리 퍼져 있습니다. Chrome, Firefox, Edge는 이를 기본적으로 구현하여 원활한 경험을 제공합니다. Node.js 또한 Temporal을 지원하지만 현재는 실험적 플래그가 필요합니다. Safari는 아직 완전히 통합되지 않은 마지막 주요 브라우저로 남아 있지만, Safari Technology Preview에서 기능을 미리 살펴볼 수 있습니다.
모든 곳에서 완전한 기본 지원이 이루어질 때까지 기다릴 필요 없이 지금 바로 Temporal의 강력한 기능을 활용할 수 있습니다. 공식 @js-temporal/polyfill을 설치하여 오늘부터 사용을 시작하세요. 이 폴리필은 모든 환경에서 코드가 일관되게 실행되도록 보장하며, 기존 Date 객체의 골치 아픈 문제들로부터 자유로워질 수 있게 합니다. 지금 명확하고 불변하는 시간 개념을 도입하여 애플리케이션의 미래를 대비하세요.
자주 묻는 질문
JavaScript의 Temporal API란 무엇인가요?
Temporal은 기존 Date 객체를 대체하기 위해 설계된 현대적이고 강력한 내장 JavaScript API입니다. 시간대에 대한 일류 지원과 함께 날짜 및 시간을 다루기 위한 포괄적인 도구 세트를 제공합니다.
Temporal API가 기존 Date 객체보다 더 나은 이유는 무엇인가요?
Temporal은 여러 핵심적인 측면에서 Date 객체를 개선했습니다. 객체가 불변(immutable)이어서 실수로 인한 버그를 방지하고, 서로 다른 개념(예: PlainDate, PlainTime)에 대해 별도의 타입을 사용하며, 명시적이고 신뢰할 수 있는 시간대 및 일광 절약 시간 지원을 제공합니다.
Temporal이 Moment.js나 Luxon 같은 라이브러리를 대체하나요?
많은 일반적인 사용 사례의 경우, 그렇습니다. Temporal은 이전에 타사 라이브러리가 필요했던 날짜 및 시간 조작에 대해 기본적이고 표준화된 솔루션을 제공하여 추가 종속성의 필요성을 없애고 번들 크기를 줄여줍니다.
Temporal API는 언제 모든 브라우저에서 사용할 수 있게 되나요?
Temporal은 ES2027 표준의 일부이며 이미 Chrome, Firefox, Edge에서 기본적으로 지원됩니다. Safari에서의 완전한 기본 지원을 기다리는 동안, 개발자들은 공식 @js-temporal/polyfill을 사용하여 오늘 모든 환경에서 이를 사용할 수 있습니다.

