moment-timezone을 이용한 UTC Offset 출력 방법

KJH·2022년 1월 18일
1

개요

사내 프로젝트 진행 중 요구사항으로
사용자가 지정한 시간대(timezone)를 기준으로 모든 시간 관련 출력을 UTC Offset 기준으로 표시 하려고 한다.

예시)

한국시간대 설정 => 2022-01-18 21:00:00(UTC+09:00)
미국 LA 시간대 설정 => 2022-01-18 04:00:00(UTC-08:00)
모스크바 시간대 설정 => 2022-01-18 15:00:00(UTC+03:00)

UTC 란 : 출처(하쿠나마타타님 UTC란)

UTC (Universal Time, Coordinated)는 1972년 1월 1일 세계 표준시로 규정되었다. 
GMT 시간은 그리니치 천문대를 지나는 태양을 기준으로 하기 때문에 지구의 자전 주기와 
밀접한 관련이 있다. 하지만 시간이 흐를 수록 지구의 자전 흐름이 늦어지고 있기 때문에 
새로운 표준시 제정에 대한 요구가 나오게 되었다. 
이에 GMT 시간 대신 국제 원자시TAI, International Atomic Times)를 기준으로 시간을 제정하였다. 
국제 원자시는 세슘 원자의 진동수에 기반하여 측정된 시간이다.

시간대(timezone) 선택 구현

  • 시간대(timezone) 선택은 간단한 Select로 구현하고 선택된 시간대를
    @react-native-async-storage/async-storage 로 저장하여 관리하였다.

  • 사용한 timezone 배열
    timezones: ["America/Los_Angeles", "Asia/Seoul", "Europe/Moscow"],

시간대를 적용한 시간 출력

  • javascript를 이용하여 구현이 가능하지만 moment-timezone을 이용하여 구현하였다.
  • moment-timezone
import moment from "moment-timezone";

moment().tz("Asia/Seoul").format('YYYY-MM-DD HH:mm:ss');

UTC 시간 출력

// UTC+00:00 기준 시간 출력: 2022-01-18 14:00:00
moment().tz("Asia/Seoul").utc().format('YYYY-MM-DD HH:mm:ss');

UTC Offset 출력하기

이제 이 글의 핵심인 Offeset을 출력해 보도록 하자.
한국시간대 기준 UTC+09:00에서 +09:00의 의미는 UTC의 기준시간 보다 9시간이 빠르다는 의미이다.
시간대(timezone) 기준 offset을 출력하는 방법에는 format에 "Z"를 추가해 주면 된다.

moment().tz("Asia/Seoul").format('YYYY-MM-DD HH:mm:ss Z');

UTC Offset 커스텀

  • UTC offset을 원하는 포멧대로 출력하고 싶다면 번거롭지만 직접 구현한다.
import moment from "moment-timezone";

export default function UseTimezone({ time, format = "YY/MM/DD HH:mm" }) {
  const UTC = `UTC${moment().format("Z")}`;
  const timeString = time && (`${moment(time).format(format)}(${UTC})`) || UTC;
  return timeString;
}

<UseTimezone time={time} />
// 2022-01-18 21:00:00(UTC+09:00)

전역변수로 관리하기

  • 매번 moment().tz(timezone)을 넣어서 출력하기엔 코드가 길어진다.
  • 최상위 파일에서 moment.tz.setDefault(timezone)을 선언하여 사용자가 시간대를 변경할 때마다 timezone을 지정해주면 moment-timezone 을 사용하는 전역에 반영되어 .tz(timezone)이 생략 가능하다.
  • moment().format('YYYY-MM-DD HH:mm:ss Z')
profile
항상 공부하는 N년차 개발자입니다.

0개의 댓글