3P by GN⁺ 6시간전 | ★ favorite | 댓글 5개
  • 자바스크립트의 Date 객체 한계를 근본적으로 대체하는 새로운 표준 Temporal API가 9년간의 개발 끝에 ECMAScript Stage 4에 도달
  • Temporal은 불변(immutable) 타입, 명시적 시간대·달력 지원, 나노초 단위 정밀도를 제공하며, 기존 Date의 모호성과 오류를 제거
  • Bloomberg, Igalia, Microsoft, Google, Mozilla 등 다양한 기관이 협력해 사양 설계와 구현을 진행, Rust 기반 공용 라이브러리 temporal_rs 로 다중 엔진 협업을 실현
  • Temporal은 ZonedDateTime, Instant, PlainDate/Time, Duration 등 세분화된 타입을 통해 시간 연산과 국제화 달력 처리를 정확히 지원
  • 30년간의 문제를 해결한 이 표준은 자바스크립트 생태계의 협업과 개방형 혁신의 성공 사례로 평가됨

자바스크립트의 시간 처리 문제와 Temporal의 등장

  • 기존 Date 객체는 1995년 Java의 Date를 그대로 포팅한 것으로, 가변성, 불일치한 월 계산, 모호한 파싱 등으로 수십 년간 버그의 원인이 되어 왔음
    • 예: setMonth 사용 시 월말 계산 오류, ISO 유사 문자열 파싱 시 브라우저별 결과 불일치
  • 2010년대 이후 웹 애플리케이션이 복잡해지면서 Date의 한계가 심화됨
  • 개발자들은 Moment.js 등 외부 라이브러리로 문제를 보완했으나, 번들 크기 증가와 유지보수 부담이 발생
  • 2017년 Maggie Johnson-Pint가 TC39에 Temporal 제안을 제출하며 표준화 논의가 시작됨

TC39와 산업계의 협업

  • Temporal은 2018년 Stage 1에서 출발해 9년에 걸쳐 Stage 4(표준화) 에 도달
  • Bloomberg는 대규모 자바스크립트 환경에서의 시간대·정밀도 문제 해결을 위해 적극 참여
    • 요구사항: 사용자 지정 시간대, IANA 기반 역사적 시간대 정확성, 나노초 단위 정밀도
  • Igalia, Microsoft, Google, Mozilla 등과 협력하여 사양 설계 및 구현을 진행
  • Philipp Dunkel, Ujjwal Sharma, Philip Chimento, Shane Carr, Justin Grant 등 여러 엔지니어가 챔피언으로 참여

Temporal의 주요 타입과 기능

  • Temporal.ZonedDateTime: 명시적 시간대·달력·DST 보정이 포함된 불변 시각 표현
    • 예: 런던 DST 전환 시 01:30이 존재하지 않으면 자동으로 02:30으로 보정
  • Temporal.Instant: 시간대·달력 없는 절대 시점 표현, 나노초 단위 정밀도 지원
    • 동일 시점을 여러 시간대로 변환 가능
  • PlainDate / PlainTime / PlainDateTime / PlainYearMonth / PlainMonthDay: 시간대 없는 ‘벽시계형’ 타입
    • 단순 날짜·시간 표시나 계산에 적합
  • Temporal.Duration: 시간 간격 표현, 다양한 단위 변환 가능 (total({ unit: "second" }))
  • 캘린더 지원: 히브리력 등 비그레고리력 연산을 정확히 수행

구현과 표준화 과정

  • Temporal은 ECMAScript 역사상 가장 큰 사양 추가로, 약 4,500개의 테스트 케이스를 포함
  • Rust 기반 공용 구현체 temporal_rs 가 개발되어 V8, Boa 등 여러 엔진이 공동 사용
    • 장점: 진입 장벽 감소, 장기 유지보수 용이, 코드 품질 향상
  • 2024~2025년 동안 temporal_rs가 100% 테스트 통과, 다중 엔진 협업의 성공 사례로 평가됨

지원 현황과 향후 과제

  • Temporal은 이미 Firefox 139, Chrome/Edge 144, TypeScript 6.0 Beta에서 지원
    • Safari는 기술 프리뷰 단계, Node.js 26은 예정
  • 향후 과제는 웹 API와의 통합
    • 예: <input type="date"> 등 폼 요소에서 Temporal 타입 지원
    • DOMHighResTimeStamp 대체 가능성 검토 (Temporal.Now.instant() 활용 예시 제시)

협업과 개방형 혁신의 성과

  • Temporal은 9년간의 다기관 협업을 통해 완성된 표준으로,
    • Microsoft, Google, Mozilla, Bloomberg, Igalia, Boa 등 다양한 주체가 참여
  • temporal_rs공유 인프라 모델의 성공 사례로,
    • 중복 구현 비용 절감, 일관성 향상, 혁신 가속화를 입증
  • Temporal은 단순한 API 개선을 넘어, 자바스크립트 커뮤니티가 장기적 기술 부채를 해결한 협력의 증거로 평가됨
  • 30년 만에 자바스크립트는 현대적 날짜·시간 API를 갖추게 되었음

ZonedDateTime...? 너 설마..!

C 의 time.h -> Java 의 java.util.Date -> js 의 Date

Java 의 joda-time -> JSR 310 -> java.time
-> moment.js -> js Temporal

이런 흐름이군요

Hacker News 의견들
  • Temporal이 시간 관리의 복잡성을 제대로 다루도록 강제하는 점이 정말 마음에 듦
    순간(instant)과 달력 기반 datetime의 구분 덕분에 Date에서 흔히 생기던 실수를 거의 방지할 수 있음
    약간 장황하긴 하지만, 새벽 3시에 DST 버그를 고치러 불려 나가는 것보단 훨씬 나음
    • 기술적으로 말하자면, 새벽 3시에 DST 버그를 고칠 일은 일요일 외에는 거의 없을 것 같음
  • 나도 Python에서 ISO8601 날짜 파싱 문제로 거의 10년간의 고생을 했음
    2012년에 시작된 이슈가 결국 표준 라이브러리에 해결책으로 들어감
    관련 토론은 이 Google Groups 스레드에서 볼 수 있음
    • 진심으로 감사함. fromisoformat 외의 방식으로 날짜를 파싱하는 건 이제 너무 비직관적으로 느껴짐
      예전엔 ciso8601을 썼지만, 표준에 들어온 이후로는 훨씬 단순하고 안정적임
  • Firefox가 Temporal을 스펙 단계에서 구현할 수 있었던 건 André Bargull(Anba)의 덕분인데,
    그가 사실 자원봉사자로 혼자서 전부 구현했다는 점이 특히 인상적임
  • Temporal은 큰 진전이지만, 여전히 API가 마음에 들지 않음
    나는 클라이언트와 서버 간에 코드를 공유하기 때문에 데이터와 로직을 엄격히 분리하려 함
    모든 데이터를 순수 JSON으로 유지해 직렬화/역직렬화를 쉽게 하고 싶은데, Temporal 객체는 함수 속성을 가진 클래스 인스턴스라 불편함
    date-fns처럼 데이터 전용 객체에 순수 함수를 적용하는 방식이 더 좋다고 생각함
    • 이건 의도된 설계임. Temporal 타입들은 직렬화 가능하지만, JSON.parse로 자동 복원이 되지 않음
      개발자가 직접 ISO 문자열에서 올바른 객체를 재구성해야 함
      자동화하면 잘못된 타입을 다루는 위험이 있음
      문서의 Temporal.Instant reviver 예시가 참고될 만함
    • 나도 같은 문제를 자주 겪음. JSON.parse/stringify로 프로토타입이 사라지는 건 흔한 이슈임
      하지만 Temporal 팀의 선택이 옳다고 봄. 날짜·시간 로직은 단순 데이터+함수 접근보다 타입 안정성이 중요함
      객체에 연산을 묶으면 PlainDate가 실수로 ZonedDateTime으로 처리되는 걸 방지할 수 있음
      tRPC 같은 곳에서는 Temporal.from()과 toString()을 경계에서 변환하는 얇은 레이어만 추가하면 충분함
      약간 번거롭지만, 타입 안정성을 포기하는 것보단 낫다고 생각함
    • 사실 JavaScript의 Date 인스턴스도 같은 문제를 가짐
      Date.toJSON은 있지만, JSON 파싱 시 문자열을 다시 Date로 변환해야 함
      Temporal도 마찬가지고, date-fns도 결국 네이티브 Date 인스턴스를 다룸
    • 모든 Temporal 객체는 .toString()Temporal.from()으로 쉽게 직렬화/역직렬화 가능함
    • JSON.parse가 자동으로 Temporal 객체를 생성하도록 바꾸는 건 과도한 접근이라고 생각함
      Date와 마찬가지로
      serialize: instant.toJSON()
      deserialize: Temporal.Instant.from(jsonDate)
      
      이런 식으로 명시적으로 처리하는 게 맞음
  • Temporal이 승인되어 정말 기쁨
    오랫동안 노력한 모든 챔피언들에게 축하를 보냄
    지난 몇 년간 temporal_rs 작업을 하며 즐거웠음
  • Java의 시간 API 개선 여정(Joda-Time → JSR 310 → Java 8)을 함께 언급했으면 흥미로웠을 것 같음
    JavaScript의 급진적 제안이 2018년에 나왔으니, Java의 접근이 어느 정도 영향을 줬을지도 궁금함
    • Joda가 Moment.js에 영향을 주고, 그게 다시 TC39 논의에 반영된 것으로 보는 게 맞음
      TC39는 다른 언어의 선례를 참고하되, JavaScript에 최적화된 방향으로 합의를 이룸
      이번 API는 9년에 걸쳐 JS 전문가들이 설계한 가장 완성도 높은 구현이라고 생각함
    • 맞음, JavaScript도 Java에서 나쁜 버전의 Date를 가져왔었음
      관련 내용은 이 HN 스레드에서도 볼 수 있음
  • “Mocha 시절 Ken Smith가 Java의 Date 코드를 C로 포팅했다”는 말이 재밌음
    왜냐면 Java의 util.Date 자체가 거의 C의 time.h API 포트였기 때문임
  • Safari가 Temporal을 부분 지원한다는 걸 보고 웃음이 나왔음
    이제 Safari가 IE의 정신적 후계자가 된 듯함
    • Safari는 새 기능 도입이 느리지만, 그래도 꾸준히 구현 중임
      IE의 문제는 느림이 아니라, 지배적 위치에서 멈췄던 것이었음
      지금은 Chrome이 제국의 자리에 있고, 오히려 Safari와 Firefox가 더 필요함
      Chrome 전용 사이트가 늘어나는 게 진짜 문제임
    • 2026년이 되어도 모바일 Safari에 네이티브 날짜 선택기가 없을 것 같음
  • Temporal에 interval 타입이 있었으면 좋겠음
    const D = new Temporal()
    const t = new Interval({minutes:5})
    const v = D.add(t)
    
    • 그건 Duration임
      const D = Temporal.PlainDate.from("2020-06-16");
      const t = Temporal.Duration.from({ day: 1 });
      const v = D.add(t) // 2020-06-17
      
      MDN 문서 참고
    • 맞음, 그건 Duration이라고 부름
  • 이걸 위해 9년 동안 1배속으로 시간 여행을 해준 팀에 감사함