서비스 timezone issue와 해결책

오준상·2022년 7월 28일
0
post-thumbnail

TimeZone Issue 발생!

회사에서 일을 하다가 특정 시간대에 땅! 하고 오픈해야 하는 기능이 있었다. (물론 내가 하던 일은 아님)
자바스크립트로 new Date()를 이용해서 현재 시간을 가져왔다. 이를 백엔드에서 넘긴 시간과 비교해서 오픈 유무를 판단했다.
이렇게 하니 문제가 생겼다. javascript의 new Date()는 유저가 위치한 TimeZone의 시간을 반환한다.
그리고 서버는 UTC를 사용한다. 그래서 우리는 서버에서 9시간을 뺀 시간으로 비교 연산을 하고 있었는데, 외국에서 서비스에 접근하면 외국의 timezone으로 현재 시간이 가져와진다.
이는 현지에서 오픈해도 외국의 TimeZone을 가진 유저는 서비스를 이용하지 못한다는걸 의미한다.
물론 지금은 해결했다 (해당 티켓을 들고 계시던분이..)

그럼 어떻게 해결하지...?

지금 생각나는건 3가지 방법이 있다.

  1. frontend timezone을 하나의 timezone으로 고정한다. (백엔드와 똑같은 timezone으로)
  2. server에서 server timezone의 now(현재 시각)를 받는다.
  3. 시간으로 판단해야 하는 로직을 백엔드에서 모두 처리하고 활성화 유무를 response로 받는다.

1.frontend timezone을 하나의 timezone으로 고정하기

회사분이 이 방법으로 해결했다. 2,3번 방법은 백엔드의 도움이 필요하고 빠르게 처리할 수 없었기 때문이였다.
방법은 다음과 같다.

const response = await serverRequest();
const date = new Date(dateString);
const utcDate = new Date(
  date.getUTCFullYear(),
  date.getUTCMonth(),
  date.getUTCDate(),
  date.getUTCHours(),
  date.getUTCMinutes(),
  date.getUTCSeconds(),
);

if (utcDate >= response.cutlineDate) { ... }

비교 연산에 사용하는 new Date()를 위에서 만든 utcDate로 교체해서 사용한다.
그러면 어디에서 접근하여 서비스를 사용하던지 무조건 UTC로 시간을 가져와서 서버 시간과 비교하기 때문에 위치에 따라서 시간이 어긋날 일은 없다.
하지만 이런 일이 일어날 때를 항상 알고 utcDate로 대체해서 사용해야 한다는 사실을 알고 있어야 해서 땜빵용으로 쓰기 좋은 것 같다.
물론 전체 new Date()를 utcDate로 대체해도 될 것 같기는 한데.. javascript 내부 class를 교체한다는게 언어적으로 얼만큼의 파급효과를 일으킬지 모른다.

2. server에서 server timezone의 now를 받는다

이는 서버 response에 now라는 값을 추가하고, 이 값에다가 server timezone으로 현재시간을 뽑아서 넘겨준다.
그리고 이 값을 기반으로 시간을 비교해서 넘긴다.

const response = await serverRequest();
if (response.now >= response.cutlineDate) {...}

3. server에서 오픈 여부를 판단 해서 response로 넘겨준다.

말 그대로 프론트에서 처리하던 로직을 백엔드에서 한 후 그 결과를 response로 넘겨주는 방식이다.
개인적으로 이 방식이 가장 안정적이라고 생각은 들지만, 백엔드와의 합의가 필요하다.

const response = await serverResponse();
if (response.isOverCutlineDate) { ... }
profile
만들고싶은걸만듭니다

0개의 댓글