-
[JS] 날짜와 시간을 관리하기 위해 Luxon 라이브러리 사용하기JavaScript 2021. 11. 8. 18:05반응형
환경
- FE : Javascript - `<input type="datetime-local">`
- BE : Java - `LocalDateTime`
- FE, BE 통신 : Axios를 이용한 Json 통신
기능 :
1. input으로 날짜를 받아서 BE에(LocalDateTime형태) 전달하여 저장
- input Format : yyyy-MM-ddTHH:mm
- BE 전달 Format : (동일)
2. 1에서 저장했던 값을 BE에서 받아서 다시 input에 뿌려주기
- BE Format : yyyy-MM-ddTHH:mm:sss
- input Format : yyyy-MM-ddTHH:mm
필요 사항 :
- 초까지 있는 데이터를 받아서, 분단위 절삭하는 기능
1. 시간을 받아서, Formatter를 적용할 수 있는 Date 비스무리한 객체로 만드는 기능
2. 1번에서 생성한 객체에 Formatter를 적용하여 원하는 형식으로 반환하는 기능
1. 직접 구현
const toDateTimeWithOutFormat = (dateTimeWithFormat) => { return new Date( dateTimeWithFormat.substring(0, 4), dateTimeWithFormat.substring(5, 7) - 1, dateTimeWithFormat.substring(8, 10), dateTimeWithFormat.substring(11, 13), dateTimeWithFormat.substring(14, 16) ); }; const toDateTimeWithFormat = (dateTime) => { const pad = (number) => { if (number < 10) { return "0" + number; } return number; }; return ( dateTime.getFullYear() + "-" + pad(dateTime.getMonth() + 1) + "-" + pad(dateTime.getDate()) + "T" + pad(dateTime.getHours()) + ":" + pad(dateTime.getMinutes()) ); };
2. Luxon 라이브러리 사용
# 설치 npm install --save luxon
const DATETIME_ISO_FORMAT = "yyyy-MM-dd'T'HH:mm"; // 위의 toDateTimeWithOutFormat() 같은 기능 // value : 2021-11-13T19:09 or 2021-11-13T19:09:00 // dateTime : DateTime { ts: 1636798140000, _zone: SystemZone, ... } const dateTime = DateTime.fromISO(value); // 위의 toDateTimeWithFormat() 같은 기능 // result : 2021-11-18T02:54 // input에 넣을 경우 문제 없음 && json으로 보내면 Gson이 LocalDateTime으로 자동 변환 const result = dateTime.toFormat(DATETIME_ISO_FORMAT); // 사용하지 않음 (Custom Formatter 사용한 이유) // resultIso : 2021-11-03T14:48:00.000+09:00 // input에 넣을 경우 에러 - The specified value "2021-11-03T14:48:00.000+09:00" does not conform to the required format. The format is "yyyy-MM-ddThh:mm" followed by optional ":ss" or ":ss.SSS". // json으로 보내면 Gson이 LocalDateTime으로 자동 변환하지 못해서 예외 발생 const resultIso = dateTime.toISO(); // # 2021-11-09T14:48:00.000+09:00 // 현재시각 new Date() // js Date 객체 DateTime.now() // luxon DateTime 객체
Luxon 라이브러리를 사용한 이유
처음엔 Moment.js 라이브러리를 사용하려고 했으나, legacy project로 전환됨 [LINK]
Moment.js란?
- 수백만 개의 프로젝트에서 성공적으로 사용
- 웹에서 날짜와 시간을 개선하는 데 기여
- 2020.09 기준 주당 1,200만 다운로드 이상을 기록
단점
- Moment는 예전 JS 생태계를 위해 구축되어 현대의 웹과는 잘 맞지 않음
- 수년에 걸쳐 발전해왔지만, 2011년 생성되었을 때와 본질적으로 동일한 디자인을 가지고 있음
- 의존하는 프로젝트의 수가 많아, 새로운 기능보다 안정성을 우선시하고 있음
- 불변이 아님(mutable - 많은 불만 사항)
- 최신 Tree Shaking 알고리즘에서 잘 동작하지 않음, 웹 애플리케이션 번들의 크기가 증가하는 경향이 있음
- 국제화 또는 시간대 지원이 필요한 경우에도 사이즈가 커질 수 있음
- 최신 웹 브라우저(Node.js 등)는 ECMA-402로 코드화된 Intl 객체를 통해 국제화와 시간대 지원을 제공
- 대안 라이브러리들은 이런 이점을 활용하여 사용자 자신의 데이터 파일을 전송해야하는 필요성을 감축
Moment.js의 레거시 프로젝트 전환
- Moment 팀에서는 기존 프로젝트에서 계속 Moment를 사용할 수 있지만, 새로운 프로젝트에서는 Moment가 사용되지 않도록 하고 싶음
- 레거시 프로젝트로 전환
1. 새로운 기능을 추가하지 않음
2. (앞으로도) Immutable을 지원하지 않음
3. Tree Shaking이나 번들 크기 문제에 대해 고려하지 않음
4. 주요 변경이 일어나지 않음
5. 오랫동안 있었던 버그 또는 동작상의 문제를 수정하지 않을 수 있음
- 기존 프로젝트에서 Moment를 사용하기 때문에, 지원하는 부분
1. 중요한 보안 문제 발생 시 해결 예정
2. IANA Timezone DB 릴리즈 후 Moment-Timezone에 대한 데이터 업데이트를 릴리즈할 예정
새로운 프로젝트에서 Moment를 사용하는 경우
1. 브라우저 지원
- Moment는 IE 8 ~, Luxon은 IE 10 ~ 지원 (Day.js는 IE 8 ~을 지원하므로 고려해볼 수 있음)
- Safari, 또는 모바일 일부 브라우저를 지원해야 하는 경우
2. 다른 라이브러리와의 종속성
- 날짜 선택기, 그래프 라이브러리 등 다른 여러 라이브러리가 Moment를 종속성으로 사용하고 있는 경우
3. Moment API의 오랜 사용자인 경우
- Moment API와 제한 사항을 잘 이해하고 있는 경우
- 단, 위에 언급한 단점이 문제가 되지 않는 경우
권장하는 대안 라이브러리
Luxon, Day.js, Date-fns, js-Joda권장하는 대안 라이브러리를 비교했을 때, Luxon의 사용이 가장 간단해 보였음
- 별도 사용자 지정 데이터 파일이나, 플러그인, 동반 라이브러리가 없고 기존에 Moment.js가 익숙하진 않은 상황이었기 때문
Luxon
- Moment 진화판같은 느낌
- Locales: Intl 제공
- Time Zones: Intl 제공
Day.js
- 유사한 API를 사용하여 Moment.js를 최소한으로 대체하도록 설계
- Moment API 사용에 익숙하고, 빠르게 이동할 수 있다면 고려
- Locales: 개별적으로 가져올 수 있는 사용자 지정 데이터 파일
- Time Zones: 플러그인을 통해 제공된 Intl
date-fns
- JavaScript Date 객체를 조작하기 위한 기능을 제공
- Locales: 개별적으로 가져올 수 있는 사용자 지정 데이터 파일
- Time Zones: 별도의 동반 라이브러리
js-Joda
- 자바 SE 8 java.time 패키지의 JSR-310 구현을 위한 Java's Three-Ten Backport의 JavaScript port.
- java.time, Joda-Time, Noda-Time에 익숙하다면 추천
- Locales: 추가 기능 모듈을 통한 사용자 지정 데이터 파일
- Time Zones: 추가 기능 모듈을 통한 사용자 지정 데이터 파일
라이브러리 없이 구현하기
- Date 객체와 Intl 객체가 필요한 요구를 충족시키고, 제한 사항을 완전히 이해한다면 직접 사용하는 것을 고려할 수 있음
JavaScript 자체 기능으로 날짜와 시간을 다룰 수 있게 될 날이 빨리 오면 좋을 것 같긴 하다.
TC39 Temporal Proposal을 통해 진행중인 것 같긴 한데, 나중에 한 번쯤 봐보면 좋지 않을까.
https://tc39.es/proposal-temporal/docs/index.html
아직 필요한 라이브러리를 찾는 것이 익숙하지 않다. 더더욱 익숙하지 않은 Java Script라 더 그런 것 같다.
사실 다수의 사람이 필요하다고 생각하는 기능인 경우엔 많은 라이브러리들이 있기 마련인데, 아직까지는 찾아볼 생각을 주도적으로 하지 못해서 아쉽다.
이미 구현된 라이브러리를 쓰면 이미 누군가 잘 구현해놓은 기능을 재구현하지 않아도 되어 시간이 절약될 뿐만 아니라, 나중에 확인하거나 수정할 때도 라이브러리의 문서를 참고할 수 있기 때문에 더 용이한 것 같다.
앞으로도 열심히 공부하는 걸로 :9
반응형