[js, Django] Timezone 적절하게 사용하기

ARA JO·2020년 11월 21일
1

Simtime 개발일지

목록 보기
3/7
post-custom-banner

javascript와 Django 적절한 Timezone (DateTime)사용하기.

Timezone

1. Unix Time

  • 1970-01-01 UTC 에서의 경과시간(or 밀리초)로 환산한 숫자.

    • 즉, 타임존과 상관없이 어디서나 일정한 값
  • 한번에 인지하기 어렵지만 다양한 언어와 환경에서 Date처리 시 즉시 변환 가능

  • 시간대가 다른 서비스 사용하는 경우 혹은 서비스 확장 시 용이.

  • 제한된 정보 표현이 불편 - 시간 정보 없이 날짜만 사용하는 경우 표현이 애매하다

{
  "unix_time_date":1521763200000,
  "iso_8601_date":"2018-03-23",
  "iso_8601_month":"2018-03",
  "iso_8601_year":"2018"
}

2. ISO-8601

  • 사람이 인식할 수 있는 문자
  • 현 UTC를 기준으로 지역에 따라 +,- (ex. 한국은 +9:00)
  • 언어와 버전에 따라 미지원되는 경우 존재
    • JavaScript의 경우 Date에서 RFC2822 또는 ISO 8601를 지원하는데 IE9 미만에서는 ECMAScript 5를 하지 못하기 때문에 바벨과 같은 트랜스파일러를 사용하는 것과 같은 주의가 필요하다.
  • 시간대가 다른 서비스 사용하는 경우(서머타임?) 혹은 서비스 확장, 환경 변화 시 번거로운 일이 발생할 수 있다.
  • 제한된 정보 표현이 편리
  "unix_time":1521739975,
  "unix_time_milisecond":1521739975123,
  "iso-8601":"2018-03-22T17:32:55+09:00",
  "iso-8601_timestamp":"2018-03-22T17:32:55.123+09:00"

Default?

1. Django

naive와 aware

https://docs.djangoproject.com/en/3.1/topics/i18n/timezones/

settings.py

USE_TZ = True
TIME_ZONE = 'Asia/Seoul'

USE_TZ로 timezone을 사용할 것을 명시하고, timezone기준이 Asia/Seoul임.

더 정확히 말하면 timezone-aware 의 사용여부

'A boolean that specifies if datetimes will be timezone-aware by default or not'

https://docs.djangoproject.com/en/3.1/ref/settings/

datetime으로 본 naive와 aware

datetime.datetime(2020,11,21,0,58,102020) #naive -정확한 기준이 미명시

datetime.datetime(2020,11,21,0,58,102020 tzinfo=) #aware

"2020-11-21" 라는 날짜를 Asia/Seoul를 기준으로 한 시간이므로

2020-11-21T00:00:00.000+09:00 (iso-8601_timestamp으로 표현) 이다.

서비스에서는 되도록 aware를 사용하자.

2. Postgresql

ISO-8601 사용

3. JavsScript

유닉스 타임스탬프를 사용한다.

https://medium.com/@pks2974/javascript-%EC%99%80-date-%EB%82%A0%EC%A7%9C-cf638c05f8f3

Date format and time zone conversions

There are several methods available to obtain a date in various formats, as well as to perform time zone conversions. Particularly useful are the functions that output the date and time in Coordinated Universal Time (UTC), the global standard time defined by the World Time Standard. (This time is historically known as Greenwich Mean Time, as UTC lies along the meridian that includes London—and nearby Greenwich—in the United Kingdom.) The user's device provides the local time.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

python으로 부터 날아온 ISO 8601 형식의 문자열을 js의 unix timestamp로 변환해준다.

Django <-> JS

1. ISO-8601 -> UNIX (from python to js)

response에서 가져올 때 : Date.parse()

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

2. UNIX -> ISO-8601 (from js to python)

request에 담을때 : Date.toISOString()

const today = new Date('05 October 2011 14:48 UTC');
console.log(today.toISOString()); // Returns 2011-10-05T14:48:00.000Z

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString

toISOString은 ECMA-262 제5판에 표준으로 자리잡았습니다. 아직 지원하지 않는 환경에서는 다음 코드를 추가해 대체할 수 있습니다.

if (!Date.prototype.toISOString) {
  (function() {

    function pad(number) {
      if (number < 10) {
        return '0' + number;
      }
      return number;
    }

    Date.prototype.toISOString = function() {
      return this.getUTCFullYear() +
        '-' + pad(this.getUTCMonth() + 1) +
        '-' + pad(this.getUTCDate()) +
        'T' + pad(this.getUTCHours()) +
        ':' + pad(this.getUTCMinutes()) +
        ':' + pad(this.getUTCSeconds()) +
        '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
        'Z';
    };

  }());
}

결론(simtime 적용기)

ISO-8601 방식으로 request, response를 작성하고, DB에도 ISO-8601방식으로 저장된다.

즉, 유저에게 보여줄 때를 제외하고 모두 ISO-8601 방식을 사용한다. 모든 작업을 끝내고 마지막 Client에서 js가 유저의 시스템 타임 설정에 따라 timezone으로 변환하여 보여주도록 하자.

파이썬의 시간대에 대해 알아보기에 따르면 장기적으로 보존이 필요한 데이터는 UTC를 기준으로 저장하는 것이 안정적이고, 추가 작업이나 혼선을 줄일 수 있다고 한다.

(지역 시간대는 생각보다 자주 바뀐다고 한다. 가령 1961이전까지 한국은 UTC+8:30이었다.)

참고

REST API 날짜/시간 표현 정하기

Django timezone 문제 파헤치기

파이썬의 시간대에 대해 알아보기

profile
Sin prisa pero sin pausa (서두르지 말되, 멈추지도 말라)
post-custom-banner

0개의 댓글