JS Date 객체의 timezone과 UTC의 차이

Maliethy·2022년 12월 22일
0

javascript

목록 보기
5/5

issue


예컨대 사용자가 달력에서 2022.12월을 선택했을 때 request parameter로 보내는 시간을 Epoch timestamp을 기준으로 12월 1일 정오(AM 00:00:00.000) 부터 12월 31일 자정 1밀리초 전(PM 12:59:59.999)로 보내야하는데 나는 local time 기준으로 보내고 있었다.

  /**
   * selectedMonth를 한달 기간의 timestamp로 변경
   * @param {Object} state
   * @returns {Array}
   */
  getterSelectedMonthToTimeStamp: ({ filterOptions }) => {
    const dateFormat = 'yyyy-MM';
    const dateObject = new Date();

    const selectedMonth = parse(filterOptions.selectedMonth, dateFormat, dateObject);

    return [
      selectedMonth.setHours(12, 0, 0, 0),
      afterMonths(selectedMonth, 1).setHours(12, 0, 0, 0),
    ];
  },

solution

epoch time

epoch time이란 unix time, POSIX time이라고도 하는데, 1970.1.1을 시작으로 나타내는 milliseconds(1/1000초) 단위의 숫자이다.

epochconverter란 사이트를 이용하면 local time을 Epoch timestamp로 쉽게 변환할 수 있다.
예를 들어 현재 내가 있는 서울 기준으로 시간이 2022년 12월 19일 월요일 오전 2:49:13 GMT+09:00 라면 Epoch timestamp은 1671385753이다.

그럼 ISO는 또 뭔가라는 의문이 생겼다.

ISO 8601 형식

ISO는 타임스탬프 표현하는 한가지 방법이다.

서버와 클라이언트 간 요청과 응답 시 전달되는 페이로드에 포함되는 타임스탬프는 어떻게 표현할 수 있을까요? 일반적으로 시스템 또는 개발자의 선호도에 따라서 UTC 기준의 Epoch라는 숫자 형태 또는 RFC 3339의 ISO 8601 형식으로 문자열 형태로 표현하게 됩니다. 더 나은 API 설계 시에는 ISO 8601 UTC를 사용해야한다는 관점이 있지만 간을 문자열로 표현하는 것에는 윤초 문제가 포함되어있기 때문에 윤초를 무시한 밀리초 단위의 유닉스 시간을 사용할때에도 있습니다. 예를 들어, 유튜브의 경우 사용자의 이벤트 트래킹을 위해 로그 이벤트를 전송할 때에 밀리초 단위의 정수값을 전달하고 있습니다.
출처: https://kdevkr.github.io/unix-timestamp/

자바스크립트 Date 객체의 기준시는?

자바스크립트의 Date객체는 브라우저가 실행되는 운영체제에 설정된 타임존으로 설정된다. 따라서 js의 Date객체에 setHour를 한다면 클라이언트의 로컬 시간을 기준으로 변경된다.

자바스크립트의 Date 객체는 내부적으로 유닉스 시간과 같은 절대값으로 시간 데이터를 관리한다. 하지만 생성자나 parse() 함수, getHour(), setHour() 등의 메소드들은 모두 클라이언트의 로컬 타임존 (정확히는 브라우저가 실행되는 운영체제에 설정된 타임존)에 영향을 받는다. 그러므로 사용자가 입력한 데이터를 이용해 그대로 Date 객체를 생성하거나 값을 지정한다면 그 데이터는 클라이언트의 로컬 타임존을 그대로 반영하게 될 것이다.
출처: https://meetup.nhncloud.com/posts/130

따라서 내가 원하는 시간(epoch time 기준 AM 00:00:00)을 만들기위해서는 local time에 9시간씩 수동으로 더해준다. 그러면 예를 들어 로컬 AM 09:00:00을 epoch time 기준으로 치환하면 AM 00:00:00이 된다.

  /**
   * betweenDate를 timestamp로 변경
   * @param {Object} state
   * @returns {Array}
   */
  getterBetweenDateToTimeStamp: ({ betweenDate }) => {
    const dateObject = new Date();
    const [date1, date2] = betweenDate;
    const dateFormat = 'yyyy-MM-dd';

    if (!date1 || !date2) {
      return [];
    }

    const [d1, d2] = [date1, date2].map((it) => parse(it, dateFormat, dateObject));

    // local time 기준 Date 객체 -> epoch time 기준으로 오전 12:00:00:00 - 오후 11:59:59:999 으로 변경
    return [
      d1.setHours(9, 0, 0, 0),
      d2.setHours(32, 59, 59, 999),
    ];
  },
profile
바꿀 수 있는 것에 주목하자

0개의 댓글