Timezone과 관련된 해외에서의 시간변환에 대한 생각

리액트만패는젊은이·2024년 6월 18일

ReactNative 공부기록

목록 보기
6/12
post-thumbnail

현재 서비스 중인 우리 앱은 한국 사용자들을 타겟으로 만들어졌고 사용중이다.
하지만 해외에서 우리 서비스를 이용하면 시간이 잘못 읽혀지고 쓰여지고 있는 문제가 발생하고 있다.

이를 해결하기위해서 dayjs() 라이브러리의 dayjs.tz.setDefault 를 이용해서 한국의 시간으로 변환하려 했으나 react-native에서는 작동되지 않는다는것을 깨달았다.

그에대한 다른방법으로 dayjs()에서 주어지는 시간을 직접 변환하는게 좋겟다는 생각으로 개발을 시작하게 된다.

목표

  • 한국과 현재 머물고 있는 해외의 utc offset을 찾는다
  • 현재 머물고 있는 해외의 시간을 한국 시간으로 변환한다.

일단 개념부터 알고 넘어가자

UTC (Coordinated Universal Time) 협정세계시

  • 국제적인 표준 시간의 기준으로 쓰이는 시각을 말합니다. 1972년 1월 1일부터 시행된 국제 표준시로, 국제 사회가 사용하는 과학적 시간의 표준입니다. 기존에 사용하던 평균태양시 기준의 그리니치 표준시(GMT)를 대체하여 사용하기 시작한 표준시입니다.

GMT(Greenwich Mean TIme) 그리니치 평균시

  • 그리니치 평균시 또는 그리니치 표준시는 런던을 기점으로 하고, 웰링턴을 종점으로 설정되는 협정 세계시의 기준시간대입니다. 1972년 1월 1일 부터 협정 세계표준시(UTC)를 공식 표현으로 쓰지만 아직도 쓰이고있다.

KST(Korean Standard Time) 한국 표준시

  • 한국 표준시는 대한민국과 조선민주주의인민공화국의 표준시로, 일본 표준시와 같은 동경 135도를 기준으로 하여 UTC보다 9시간 빠른 표준시(UTC+09:00)입니다.

일단 결론부터 말하고 넘어갑니다.

아래에 제시된 방법은 정답이라고는 생각되지 않습니다.
과연 아래의 방법이 timezone에서의 오류를 해결하는 방법이 맞는지에 대한 의문이 계속 생긴다.
내가 생각하기에 가장 좋은방법은 client에서는 그대로 dayjs()를 쓰고
client → server로 data를 요청 하거나 data를 삽입할시에 현재 머물고 있는 국가의 UTC OFFSET 같은 특정할수 있는 값을 넘기면 server에서 변환을 하여 data를 주던가 해야될것 같다.

하지만 위의 방법으로도 client에서 변환은 절대적으로 필요하다.

아래부터는 해결방법이다

현재 위치 국가 : 필리핀
필리핀의 현재시간 dayjs() : 2024-06-17 16:00
한국의 현재시간 dayjs() : 2024-06-17 17:00
현재시간의 utcTime : 2024-06-17T08:00:000

한국의 UTC OFFSET : +540
필리핀의 UTC OFFSET : +480

utcOffset 같은 경우는 dayjs 라이브러리의 dayjs().utcOffset() 함수를 통하여 값을 얻을수 있다.

이상태에서 우리 DB의 데이터들은 utcTime으로 적재가 이루어지고 있는데 한국의 한국의 2024-06-17 17:00 시간은 필리핀의 앱에서는 2024-06-17 16:00 시간으로 보여진다.

이를 한국 시간으로 보여지길 원한다면
1. 한국의 UTC OFFSET - 필리핀의 UTC OFFSET = +60을 데이터의 시간에 더해서 보여줘야 한다.
2. 다른 방법으로는 현재 필리핀에서의 utcTime을 구한다음 한국의 UTC OFFSET인 +540 을 더하는 방법도 있다.

export const ConvertKst = (day: any) => {
 const SeoulOffset: number = 540; // 서울은 +540이다
 const SpecificCountryOffset: number = dayjs().utcOffset(); // 특정위치 국가의 offset

 if (SpecificCountryOffset === SeoulOffset) {
   return day; // 서울에 위치한다면 함수 수행 x
 } else {
   const UtcTime = dayjs(day).utc(); // 해당시간의 utcTime
   const KoreaStandardTime: Dayjs = dayjs(UtcTime).add(SeoulOffset, 'minute'); //utcTime + seouloffset
   return KoreaStandardTime;
 }
};

여기서 위의 로직을 수행한후 시간은 => 현재시간의 isoString에서 +1이 된시간이다.
여기서부터 시간이 많이 어긋나기 시작한다.
또다른 문제상황은 아래로

현재 utcTime은 2024-06-17T08:00:000 이시간인데 
필리핀에서 한국의 시간처럼 보여지기 위해서 날짜를 +1시간을한
2024-06-17T09:00:000 시간으로 변환되었다. 

이상태에서 필리핀에서 한국처럼 보이기 위한 시간을 
우리 DB에 적재하게된다면 실제 한국시간과 +1이라는 시간의 차이가 발생할것이다.

그러면 필리핀에서 한국처럼 보이기 위해 변환된 시간을 DB에 적재하는 시점에는 다시 utctime으로 변환을
해야만 한국에서 정상적인 시간으로 동작을 할것이다.

export const ConvertKstToPost = (day: any) => {
  const SeoulOffset: number = 540;
  const SpecificCountryOffset: number = dayjs().utcOffset();

  if (SpecificCountryOffset === SeoulOffset) {
    return day;
  }

  // UTC가 양수일떄
  if (SpecificCountryOffset > 0) {
    if (SeoulOffset > SpecificCountryOffset) {
      const TimeDiff = SeoulOffset - SpecificCountryOffset;
      const KoreaStandardTime = dayjs(day).subtract(TimeDiff, 'minute');
      return KoreaStandardTime;
    } else {
      const TimeDiff = SpecificCountryOffset - SeoulOffset;
      const KoreaStandardTime = dayjs(day).add(TimeDiff, 'minute');
      return KoreaStandardTime;
    }
  }
  // UTC가 음수일떄
  if (SpecificCountryOffset < 0) {
    const TimeDiff = SeoulOffset - SpecificCountryOffset;
    const KoreaStandardTime = dayjs(day).subtract(TimeDiff, 'minute');

    return KoreaStandardTime;
  }
};

1번에서 변환되었던 시간을 post요청을 할시에 위의 로직을 수행하게 된다면 한국의 시간으로 DB에 담기게 될것이다.

하지만 또다른 문제가 발생한다.

get 요청으로 온데이터들을 위의 ConvertKst() 함수를 이용해서 필리핀에서도 한국처럼 보이게 
시간을 변환시켯다고 가정한다. 

그럼 그변환된시간들을 우리 앱에서 사용중인 TimePicker 또는 DatePicker에서 value값으로 사용하게
된다면 또 시차의 오류가 발생할것이다.

utcTime : 2024-06-17T08:00:000
필리핀에서 한국에 보여지기위해 정제한후 시간 : 2024-06-17T09:00:000

위의 변환된 시간을 timepicker에서 value값으로 사용하게되면 1시간의 오차가 생긴다.
이를위해서 또한번의 변환을 시켜줘야한다.

export const ConvertLocaleTime = (day: any) => {
  const SeoulOffset: number = 540;
  const SpecificCountryOffset: number = dayjs().utcOffset();

  if (SpecificCountryOffset === SeoulOffset) {
    return day;
  }

  const LocaleTime = dayjs(day).subtract(SpecificCountryOffset, 'minute');
  return LocaleTime;
};
profile
front-end-developer

0개의 댓글