JavaScript 날짜 처리에 있어 새로운 시대의 서막
James Reed
Infrastructure Engineer · Leapcell

소개
수년 동안 JavaScript 개발자들은 Moment.js 및 Date-fns와 같은 강력한 라이브러리의 도움을 받아 날짜 및 시간 조작의 복잡성을 헤쳐왔습니다. 이 도구들은 JavaScript의 내장 Date 객체가 남긴 격차를 메우는 데 필수적이었습니다. Date 객체는 기능적이지만 사용성, 불변성, 시간대 및 국제화 처리 측면에서 종종 부족했습니다. 그러나 JavaScript 날짜 및 시간 관리의 환경은 중대한 변화의 직전에 있습니다. 새로운 표준인 Temporal API가 등장하여 정밀성, 예측 가능성 및 개발자 친화성의 새로운 시대를 열 것을 약속합니다. 이 글에서는 Temporal API가 Node.js에서 날짜 및 시간을 처리하는 방식을 혁신할 것이며, 우리가 사랑하는 레거시 라이브러리를 쓸모없게 만들 가능성이 있다는 점에 대해 자세히 알아보겠습니다.
Temporal 언패킹: 최신 날짜-시간 관리 심층 분석
Temporal의 영향을 탐구하기 전에 Temporal이 도입하는 핵심 개념과 해결하는 문제를 이해해 보겠습니다.
핵심 용어
Temporal.Instant: 달력 체계나 시간대와 무관하게 특정 시점을 나타냅니다. 이를 타임라인의 단일 절대적인 순간으로 생각하십시오.Temporal.ZonedDateTime: 특정 시간대 및 달력 체계와Instant를 결합하여 특정 위치에서의 특정 날짜 및 시간의 사람이 읽을 수 있는 표현을 제공합니다.Temporal.PlainDate: 시간 또는 시간대 구성 요소가 없는 날짜를 나타냅니다(예: "2023년 10월 26일"). 시간 컨텍스트 없이 반복되는 이벤트나 데이터베이스에 날짜를 저장하는 데 유용합니다.Temporal.PlainTime: 날짜 또는 시간대 구성 요소가 없는 하루 중 시간을 나타냅니다(예: "14:30:00").Temporal.PlainDateTime: 시간대 구성 요소가 없는PlainDate와PlainTime의 조합(예: "2023년 10월 26일, 14:30:00").Temporal.PlainYearMonth: 연도와 월을 나타내며 날짜, 시간 또는 시간대 없이 표시됩니다(예: "2023년 10월").Temporal.PlainMonthDay: 월과 날짜를 나타내며 연도, 시간 또는 시간대 없이 표시됩니다(예: "10월 26일").Temporal.Duration: "3시간 30분" 또는 "5일"과 같은 특정 기간을 나타냅니다. Temporal 객체에 대한 산술 연산을 수행하는 데 사용됩니다.
Date의 문제점과 Temporal이 해결책인 이유
JavaScript의 내장 Date 객체에는 몇 가지 오래된 문제가 있습니다.
- 가변성:
Date객체는 가변적이므로setDate()와 같은 작업은 원본 객체를 직접 수정합니다. 이는 복잡한 애플리케이션에서 예상치 못한 부작용과 버그를 유발할 수 있습니다. - 시간대 처리:
Date인스턴스는 내부적으로 UTC(협정 세계시)에 본질적으로 연결되어 있지만 문자열로 변환될 때 로컬 시간대에 따라 표시되어 혼란을 야기하고 국제 애플리케이션에 대한 신중한 처리가 필요합니다. - 모호성: 문자열 표현을
Date객체로 구문 분석하는 것은 JavaScript 엔진마다 일관성이 없으며 구현 정의 동작에 크게 의존합니다. - 명확성 부족: "날짜"와 "특정 시간대의 날짜 및 시간" 사이에 명확한 구분이 없어 개발자들이 원하는 결과를 얻기 위해 문자열 조작과
Date객체를 함께 사용하는 경우가 많습니다. - 산술 복잡성: 시간대 경계 또는 일광 절약 시간 변경을 가로질러 특히 날짜, 월 또는 연도를 특정 횟수만큼 추가하는 것과 같은 복잡한 날짜 산술을 수행하는 것은 악명 높게 어렵고 오류가 발생하기 쉽습니다.
Temporal은 객체 지향 설계와 불변성 및 명시성에 대한 강조를 통해 이러한 문제에 정면으로 대응합니다.
원칙: 불변성과 연결 가능한 작업
Temporal의 기본 원칙 중 하나는 불변성입니다. 모든 Temporal 객체는 불변적이므로 날짜를 추가하거나 시간대를 변경하는 작업은 원본을 수정하는 대신 새 Temporal 객체를 반환합니다. 이는 예측 가능성을 크게 향상시키고 버그를 줄입니다.
날짜 추가를 고려해 보겠습니다.
// Moment.js (가변) 사용 const momentDate = moment('2023-10-26'); momentDate.add(5, 'days'); // momentDate는 이제 '2023-10-31' // Temporal (불변) 사용 const plainDate = Temporal.PlainDate.from('2023-10-26'); const newPlainDate = plainDate.add({ days: 5 }); // plainDate는 여전히 '2023-10-26'이고, newPlainDate는 '2023-10-31' console.log(plainDate.toString()); // 2023-10-26 console.log(newPlainDate.toString()); // 2023-10-31
명시적인 시간대 및 달력 처리
Temporal은 시간대 및 달력 시스템 선택을 명시적으로 만듭니다. 암시적인 변환 대신 ZonedDateTime이 어떤 시간대를 참조하는지 항상 알 수 있습니다.
// ZonedDateTime 생성 const nowInLondon = Temporal.ZonedDateTime.from({ year: 2023, month: 10, day: 26, hour: 14, minute: 30, timeZone: 'Europe/London' }); console.log(nowInLondon.toString()); // 2023-10-26T14:30:00+01:00[Europe/London] // 다른 시간대로 변환 const nowInTokyo = nowInLondon.withTimeZone('Asia/Tokyo'); console.log(nowInTokyo.toString()); // 2023-10-26T22:30:00+09:00[Asia/Tokyo] // 시간대를 가로지르는 계산 수행 const futureInLondon = nowInLondon.add({ days: 1 }); console.log(futureInLondon.toString()); // 2023-10-27T14:30:00+01:00[Europe/London]
시간대를 변경할 때 시간이 올바르게 조정되어 정확한 표현이 보장됨을 알 수 있습니다.
Temporal.Duration을 사용한 강력한 날짜 산술
Temporal.Duration을 사용하면 정확하고 모호하지 않은 날짜 산술이 가능합니다.
const birthDate = Temporal.PlainDate.from('1990-05-15'); const today = Temporal.PlainDate.from('2023-10-26'); // 차이 계산 const ageDuration = birthDate.until(today); console.log(`Duration: P${ageDuration.years}Y${ageDuration.months}M${ageDuration.days}D`); // Duration: P33Y5M11D // 기간 추가 const fiveDaysThreeHours = Temporal.Duration.from({ days: 5, hours: 3 }); const plainDateTime = Temporal.PlainDateTime.from('2023-10-26T10:00:00'); const futureDateTime = plainDateTime.add(fiveDaysThreeHours); console.log(futureDateTime.toString()); // 2023-10-31T13:00:00
이 명시적인 기간 객체는 레거시 라이브러리의 모호한 add 또는 subtract 메서드의 함정을 피합니다. 여기서 add(1, 'month')는 월말에 예상치 못한 방식으로 동작할 수 있습니다(예: 1월 31일에 한 달을 추가하면 라이브러리 로직에 따라 2월 28일/29일 또는 3월 3일이 될 수 있습니다). Temporal은 이러한 "달력 인식" 작업을 우아하게 처리합니다.
Node.js에서의 응용
Temporal API는 현재 Stage 3 TC39 제안이므로 거의 최종 단계이며 구현을 사용할 수 있습니다. Node.js의 경우 폴리필(예: temporal-polyfill)을 사용하거나 공식적으로 통합된 후 최신 Node.js 버전에서 실험적 기능을 활성화하여 이를 실험할 수 있습니다.
Node.js 백엔드에서 Temporal은 다음을 위해 매우 유용할 것입니다.
- 작업 예약: 서로 다른 시간대의 cron 작업 또는 지연된 작업을 정확하게 예약합니다.
- 데이터베이스 상호 작용: 특히 다양한 지역의 사용자와 거래할 때 날짜-시간을 정확하게 저장하고 검색합니다.
- API 개발: API 응답에서 일관된 날짜-시간 형식 및 계산을 보장합니다.
- 로깅 및 감사: 로컬 서버 구성에 영향을 받지 않는 절대적인 정밀도로 이벤트에 타임스탬프를 지정합니다.
예를 들어, 전자 상거래 플랫폼이 뉴욕 오전 9시, 런던 오후 2시, 도쿄 오후 10시에 프로모션을 시작하도록 예약해야 하는 경우 Temporal의 ZonedDateTime을 사용하면 숨겨진 복잡성 없이 이러한 변환 및 비교를 간단하고 안정적으로 수행할 수 있습니다.
Moment.js 및 Date-fns에서 벗어나는 전환
Moment.js와 Date-fns는 커뮤니티에 많은 도움이 되었지만, 원래 Date 객체의 설계에 뿌리내린 아키텍처의 한계를 본질적으로 가지고 있거나 이를 추상화하려고 시도합니다. 특히 Moment.js는 더 이상 새로운 기능에 대해 적극적으로 개발되지 않으며 개발자에게 대안을 찾도록 권장합니다. Date-fns는 현대적이고 불변하지만 Temporal이 플랫폼 수준에서 해결하려고 하는 철학적 문제 중 일부에 여전히 직면해 있습니다.
브라우저 및 Node.js의 네이티브 API인 Temporal은 다음을 약속합니다.
- 번들 크기 오버헤드 없음: 타사 라이브러리를 포함할 필요가 없어 애플리케이션 크기가 줄어듭니다.
- 성능: 네이티브 구현은 일반적으로 사용자 공간 폴리필 또는 라이브러리보다 빠릅니다.
- 표준화: 모든 JavaScript 환경에서 보편적으로 이해되고 일관되게 동작하는 API입니다.
결론
Temporal API는 단순한 또 다른 날짜-시간 라이브러리가 아니라 JavaScript가 날짜와 시간을 처리하는 방식에 대한 근본적인 재고입니다. Temporal은 순간, 날짜, 시간 및 기간을 처리하기 위한 포괄적이고 불변적이며 명시적인 객체 세트를 제공함으로써 Node.js 및 더 넓은 JavaScript 생태계에서 날짜 및 시간 관리에 필요한 정밀성과 예측 가능성을 가져올 것입니다. 날짜와 시간으로 인한 악몽이 과거의 유물이 되는 미래를 대비할 때입니다. Temporal이 개발의 중요한 측면을 표준화하고 단순화하기 위해 등장합니다.

