GN⁺: JavaScript Dates가 드디어 수정 될 예정
(docs.timetime.in)- ECMAScript의 최근 변화 중 가장 주목할 만한 것은 Temporal 제안임
- 이 API는 FullCalendar 팀이 제공하는 폴리필을 통해 이미 사용할 수 있음
- 이 API의 주요 장점 중 하나는 드디어 "Zoned Date Time"을 표현하는 네이티브 객체가 생긴 것
Zoned Date Time이란 무엇인가?
- 인간의 날짜를 다룰 때, 우리는 일반적으로 시간대를 생략하고 날짜와 시간을 말함
- 그러나 JavaScript의 "Date" 객체는 숫자만 다루기 때문에 원래 날짜의 의미가 사라짐
- 예를 들어, 카드 결제 시점을 기록하려고 할 때, 많은 사람들이 다음과 같은 코드를 사용할 수 있음
const paymentDate = new Date('2024-07-20T10:30:00');
- 이는 브라우저가 사용자의 시간대(CET)를 기준으로 밀리초를 계산함. 그러나 저장된 정보는 시간대에 따라 다르게 해석될 수 있음
- 자바스크립트에서 날짜는 UTC가 아니라 윤초가 완전히 무시되는 POSIX라는 매우 중요한 사실 외에도, 숫자만 있으면 날짜의 원래 의미가 사라진다는 문제가 있음
- 많은 사람들이 UTC로 작업하거나 ISO 형식으로 날짜를 전달하면 안전하다고 생각하지만, 여전히 정보가 손실될 수 있으므로 이는 옳지 않음
UTC는 충분하지 않음
- ISO 형식으로 작업해도, 날짜를 표시할 때는 여전히 시간대 정보가 부족함
- 타임스탬프를 인간이 읽을 수 있는 날짜로 변환하는 함수는 injective(단사함수)하지 않음
- 예를 들어, 마드리드에서 시드니로 여행을 갔다가 돌아왔을 때, 은행 거래 내역의 시간대 문제로 혼란이 생길 수 있음
Temporal API 소개
- Temporal API는 시간대와 함께 날짜와 시간을 나타내는 Temporal.ZonedDateTime 객체를 도입함
- RFC 3339의 확장을 제안하여 문자열로 날짜를 직렬화하고 역직렬화하는 표준을 제시함
-
1996-12-19T16:39:57-08:00[America/Los_Angeles]
- 이 문자열은 1996년 12월 19일 16시 39분 57초를 나타내며,
- 오프셋은 UTC에서 -08:00이며 (로스앤젤레스가 속한 태평양 표준시 PST)
- 시간대를 인식하는 애플리케이션이 고려할 수 있도록 관련 표준 시간대("태평양 표준시")를 추가로 지정
- 다양한 달력 시스템을 지원함 (예: 불교, 중국, 단기, 그레고리력, 이슬람, 페르시안, 일본 등)
기본적인 연산들
날짜 생성
- Temporal API는 시간대를 처리하는 데 강력한 도구를 제공함.
- 예를 들어,
Temporal.ZonedDateTime
객체를 생성할 때 시간대가 정확하게 반영되도록 함:const zonedDateTime = Temporal.ZonedDateTime.from({ year: 2024, month: 8, day: 16, hour: 12, minute: 30, second: 0, timeZone: 'Europe/Madrid'});
- 이로 인해 시간대 변경이나 DST와 같은 지역 시간 조정에도 정확한 시간을 유지할 수 있음.
날짜 비교
- ZonedDateTime 객체는
compare
메서드를 제공하여 두 개의 ZonedDateTime을 비교할 수 있음:const one = Temporal.ZonedDateTime.from('2020-11-01T01:45-07:00[America/Los_Angeles]'); const two = Temporal.ZonedDateTime.from('2020-11-01T01:15-08:00[America/Los_Angeles]'); Temporal.ZonedDateTime.compare(one, two); // => -1
유용한 내장 기능들
-
hoursInDay
속성은 해당 날짜의 실제 시간을 반환함:Temporal.ZonedDateTime.from('2020-03-08T12:00-07:00[America/Los_Angeles]').hoursInDay; // => 23 (DST 시작일)
시간대 변환
-
withTimeZone
메서드를 사용하여 ZonedDateTime의 시간대를 변경할 수 있음:zdt = Temporal.ZonedDateTime.from('1995-12-07T03:24:30+09:00[Asia/Tokyo]'); zdt.withTimeZone('Africa/Accra').toString(); // => '1995-12-06T18:24:30+00:00[Africa/Accra]'
기본 산술 연산
-
.add
메서드를 사용하여 DST 규칙에 따라 날짜를 추가하거나 뺄 수 있음:zdt = Temporal.ZonedDateTime.from('2020-03-08T00:00-08:00[America/Los_Angeles]'); laterDay = zdt.add({ days: 1 }); // => 2020-03-09T00:00:00-07:00[America/Los_Angeles]
날짜 간 차이 계산
-
.until
메서드는 두 시간 간의 차이를 계산하고Temporal.Duration
객체로 반환함.- 예를 들어,
zdt.until(other)
와 같이 사용할 수 있음.
- 예를 들어,
결론
- Temporal API는 JavaScript에서 시간을 다루는 방식을 혁신적으로 변화시킴
- 이 기사에서는 인간이 읽을 수 있는 날짜와 UTC 날짜의 차이, 그리고 Temporal.ZonedDateTime 객체를 사용하여 이를 정확하게 나타내는 방법을 다뤘음
- 다음 기사에서는 Instant, PlainDate, Duration 등 다른 흥미로운 객체들을 탐구할 예정
GN⁺의 의견
- JavaScript 개발자들에게 오랫동안 어려움을 안겨주었던 날짜 및 시간 처리 문제가 Temporal API로 해결될 것임
- 시간대와 DST 문제를 자동으로 처리할 수 있어 글로벌 애플리케이션 개발 시 매우 유용함
- 기존
Date
객체와의 호환성 및 마이그레이션 문제는 고려해야 할 사항임 -
Temporal
API는 명확하고 직관적인 방식으로 설계되어 있으며, 다양한 캘린더 시스템을 지원하는 등 국제화 지원 측면에서도 우수함 - 이러한 변화는 JavaScript 개발자의 생산성을 크게 향상시킬 것으로 기대됨
Hacker News 의견
-
Javascript에서 날짜와 시간을 다루는 것은 매우 어려움
- Moment 라이브러리는 날짜와 시간을 혼동하여 많은 문제를 일으킴
- Python의 Arrow 라이브러리도 같은 실수를 범함
- Rust의 Chrono 라이브러리는 예측 가능하고 결함이 적음
- JS의 Date와 Moment는 사용하기 어려움
-
새로운 API가 JS의 시간대 문제를 해결할 것으로 기대됨
- 특정 시간대를 성공적으로 파싱하지만 다른 경우에는 UTC로 가정하는 문제 있음
- 이전 직장에서 이 문제로 큰 어려움을 겪음
-
타임스탬프를 인간이 읽을 수 있는 날짜로 변환하는 함수는 injective하지 않음
- injectivity와 well-definedness의 개념을 혼동함
- 타임스탬프 t에 대해 유일한 인간이 읽을 수 있는 날짜 x가 존재하지 않음
-
시간 처리에 대한 난이도 곡선에 대한 농담
- 초보자는 UTC 타임스탬프만 사용
- 중급자는 시간대를 저장하고 변환해야 한다고 주장
- 고수는 다시 UTC 타임스탬프만 사용
-
미래의 날짜 예시를 더 많이 사용하면 기사가 더 설득력 있을 것임
- 타임스탬프를 기록할 때는 UTC와 위치만 필요함
- 은행 예시는 UX 문제일 뿐 정보 손실은 아님
-
시간 처리를 이해하지 못해 불안해하는 사용자
- Python과 같은 언어에서 시간 처리 문제를 이해하는 좋은 입문서 추천 요청
-
좋은 datetime 표준을 가지는 것이 절반의 싸움임
- 나머지 절반은 널리 채택되는 것임
- 다른 시스템과의 호환성을 위해 ISO 문자열이나 unix 타임스탬프로 변환하는 것이 안전함
-
ISO 날짜 문자열이 정확한 정보를 캡처해야 함
- JavaScript나 다른 언어가 내장된 구조를 필요로 한다는 생각에 의문
- Temporal과 Date는 간단한 문제를 복잡하게 해결함
-
Postgres에서 이 문제를 어떻게 처리할지 질문
-
Temporal이 실제로 도입될 것이라는 증거가 부족함
- 여러 유망한 JS 제안들과 마찬가지로 오랜 시간 논의만 되고 있음