dayjs - utc, utcOffset

clean·2023년 10월 12일

개요

의문

// #1
dayjs.utc('2023-09-26 10:00:00').valueOf() // 1695722400000
// #2
dayjs('2023-09-26 10:00:00').utcOffset(0).valueOf() // 1695690000000

이 두개의 타임스탬프 값이 다른 이유가 궁금했다.
둘 다 23년 9월 26일 10시 UTC+0 의 타임스탬프 값으로 동일하게 나와야하는 거 아닌가?

해결

utcOffset 의 두번째 인자를 true 로 전달해야 23년 9월 26일 10시 UTC+0 타임 스탬프 값을 얻을 수 있다.

// #1 2023년 9월 26일 10시 UTC+0 에 대한 타임 스탬프 값 출력
dayjs.utc('2023-09-26 10:00:00').valueOf() // 1695722400000
// #2 2023년 9월 26일 **01**시 UTC+0 에 대한 타임 스탬프 값 출력
dayjs('2023-09-26 10:00:00').utcOffset(0, false).valueOf() // 1695690000000
// #3 2023년 9월 26일 10시 UTC+0 에 대한 타임 스탬프 값 출력
dayjs('2023-09-26 10:00:00').utcOffset(0, true).valueOf() // 1695722400000

#2, #3을 보면 utcOffset(0)이 아니라 utcOffset(0, true) 로 지정해야 #1의 실행 결과와 같은 값이 나온다.
utcOffset 의 두번째 인자가 현재 시간(=타임존 떼고 보여지는 시간, 즉 예제에서는 2023년 9월 26일 10시)을 유지할 지 여부이기 때문이다.

  • false (기본값): 표시되는 시간을 변경한다.
    • 로컬 시간을 UTC+0 의 시간대로 표시하고 싶은 경우 사용된다. (예제의 경우 UTC+0에서는 23년 9월 26일 1시)
      • 예제에서의 로컬 시간: 2023-09-26 10:00:00 (오프셋은 +9)
      • utcOffset(0, false) 적용시 로컬 시간: 2023-09-26 01:00:00 (오프셋은 +0)
    • 같은 시간 값에 대해 offset만 변경하여 표시하므로 타임스탬프 값은 변경되지 않는다.
  • true: 표시되는 시간은 고정한다.
    • 로컬 시간은 변경하지 않고 offset 만 변경할 때 사용된다.
      • 예제에서의 로컬 시간: 2023-09-26 10:00:00 (오프셋은 +9)
      • utcOffset(0, true) 적용시 로컬 시간: 2023-09-26 10:00:00 (오프셋은 +9)
    • 로컬 시간을 유지하기 위해 고유 시간값이 변경되어 타임스탬프도 변경됨
  • 예제에서의 타임스탬프/offset에 따른 시간은 아래와 같다.

더 알아보기

dayjs API

Parse - utc()

  • dayjs() 로 생성 시 로컬 타임존을 기준으로 파싱 및 표시하지만 dayjs.utc() 로 생성할 경우 UTC 타임존(UTC+0) 기준으로 파싱 및 표시한다.
    UTC 를 로컬 타임존 기준으로 변경하려면 Manipulate-utc 나 Manipulate-local을 사용해야 한다.

Manipulate - utc(keepLocalTime)

  • keepLocalTime을 true를 전달하면 로컬 시간을 변경하지 않고 Offset을 UTC+0으로 변경한다.
dayjs.extend(utc)
var a = dayjs()
a.format() //2019-03-06T08:00:00+08:00
a.utc().format() // 2019-03-06T00:00:00Z
dayjs('2016-05-03 22:15:01').utc(true).format() // 2016-05-03T22:15:01Z

Manipulate - utcOffset(offset, keepLocalTime)

  • offset: 시간 또는 분 (16 ~ -16 까지는 시간, 그 외는 분으로 처리됨)
  • keepLocalTime: keepLocalTime을 true를 전달하면 로컬 시간을 변경하지 않고 offset 만 변경한다.
dayjs.extend(utc)
// these are equivalent
dayjs().utcOffset(8)  // set hours offset

dayjs.utc('2000-01-01T06:01:02Z').utcOffset(1, true).format() 
// 2000-01-01T06:01:02+01:00

Manipulate - local()

  • 로컬 타임존 기준으로 표시, utcOffset KeepLocalTime:false 와 동일하게 고유 시간값은 변경하지 않음, 표시되는 로컬 시간만 변경됨
    • KST는 +9로 utcOffset(9) 와 동일
dayjs.extend(utc)

var a = dayjs.utc()
a.format() // 2019-03-06T00:00:00Z
a.local().format() //2019-03-06T08:00:00+08:00

개념 정리 - 타임존

지구에 흐르는 시간은 하나지만 지구의 자전에 따라 지역별로 낮과 밤의 차이가 생기는데 이를 조정하기 위해 고안된 시간의 구분선이 타임존이다.
(모든 지역에서 타임존 없이 시간을 동일하게 표기한다면 09:00 이 어떤 지역에서는 아침이고, 어떤 지역에서는 저녁일 수 있다.)

따라서 어떤 기준점(UTC, 협정 세계시)을 가지고 지역에 따른 시간 차이(offset)를 정해 로컬 시간을 표기한다.

타임존이란?

동일한 로컬 시간을 따르는 지역을 의미한다. 좀 더 정확하게 말하자면 역사적으로 표준 시간대나 DST(서머 타임)의 변경이 동일하게 적용되었던 지역이다.

그러면 역사적으로 표준 시간대가 변경된 경우도 있다는 말일까?
맞다. 타임존은 하나 혹은 그 이상의 오프셋을 가진다. 이유는 특정 시점에 법의 제정, 서머 타임 적용 등에 의해 오프셋이 달라지기도 하기 때문이다.

따라서 타임존은 단순히 오프셋으로는 말할 수 없고 역사적인 변경 내역을 알아야하는데 현재 가장 신뢰할 수 있는 표준은 IANA time zone database 이다.
타임존을 변경해서 값을 보여줘야 하는 경우 IANA time zone 을 활용한 API 를 사용해야 한다.

dayjs

Moment 지원 종료 후 대안으로 제시된 날짜관련 js 라이브러리로 IANA 를 활용한 타임존 관련 여러 API를 지원한다.

0개의 댓글