포시코딩

3월15일 - TypeORM과 UTC Time zone 문제.. 인줄 알았으나 RDS 타임존 문제.. 인줄 알았으나 내 코드 문제 본문

TIL

3월15일 - TypeORM과 UTC Time zone 문제.. 인줄 알았으나 RDS 타임존 문제.. 인줄 알았으나 내 코드 문제

포시 2023. 3. 15. 13:57
728x90

개요

개발하다보면 날짜 시간 관련해서 time zone 문제를 다들 겪어봤을 것이다.

전 세계 시간에 대해서도 영점이 존재하고 

한국 시간은 9시간을 빼줘야 영점에 맞춰지게 된다.

 

어떤 날짜 시간을 저장할 때 해당 국가의 시간이 아닌 위에서 말한 영점 시간에 맞춰져 저장이 되야 하는데

이유는 이 서비스가 그 나라뿐만 아니라 다른 나라에서도 접속이 가능할거고

시차가 존재할텐데 나는 9시에 저장했는데 

내가 있는 나라보다 1시간 빠른 나라에서 동시에 저장했어도 8시에 저장하게 되는 일이 생기는 이유 때문이다.

 

TypeORM에서 자동으로 만들어 넣어주는 createdAt, updatedAt도 자동으로

그 영점에 맞춰져 저장이 되는데 

 

내가 모임 약속 시간이라는 schedule 컬럼에 대해 

string으로 받아 TypeORM을 통해 MySQL에 저장하면 

자동으로 datetime으로 변환해주되, 9시간 전이 아닌 string으로 받은 시간 그대로 저장 되는 문제를 발견했다.

 

서론이 길었는데

위 문제에 대한 해결 방법에 대해 알아보고자 한다.

 

해결 방법

const schedule = `${scheduleDate} ${scheduleTime}`;

위 코드가 기존 코드다. 

그냥 date와 time 합쳐서 schedule 만든다음 그대로 백엔드에 보냈었다.

 

const a = new Date(`${scheduleDate} ${scheduleTime}`);
const b = a.toISOString();
const schedule = b.slice(0, 19).replace('T', ' ');

바뀐 코드다.

원래 한줄 코드로 만들었는데 설명하기 쉽게 3번에 걸쳐 변환되게 작성해봤다.

일단 new Date로 해당 날짜시간에 대해 Date 타입의 객체로 만들어준 후 

toISOString()으로 UTC 날짜시간이 되게 즉, 영점 시간이 되게 만든다.

 

이러면 원래 2023-03-15 19:00:00 이었던 값이 

2023-03-15T10:00:00:000Z 와 같이 변하는데

얼핏 보면 10:00:00이 됐기 때문에 이대로 보내면 되지 않을까 싶은데

 

나도 해봤지만 여전히 2023-03-15 19:00:00 그대로 저장되는 문제가 있었다.

그래서 여기서 한번 더 꼬아

slice()와 replcae()를 통해 2023-03-15T10:00:00:000Z를 2023-03-15 10:00:00 의 string으로 바꾸어 주었고

 

이대로 보내니 이제서야 정상적으로 9시간 전인 2023-03-15 10:00:00가 MySQL에 저장되는 모습을 확인할 수 있었다.

 

물론 기존 백엔드 코드도 업그레이드 했는데

 

@IsString()
readonly schedule: string;

기존에 DTO에서 TypeORM이 알아서 string을 datetime으로 변경해 저장해주니

이렇게 받는 안일함을 보였는데

 

@Type(() => Date)
@IsDate()
readonly schedule: Date;

애초에 DTO에서도 잘못된 schedule 날짜시간값이 들어오면 리턴되게 막아줌으로 

좀 더 완벽한 코드로 변화시켰다.

 

날짜 관련해선 개발할 때는 모르고 있다가 

본격적인 QA 할 때쯤 꼭 겪게 되는 문제인데

 

예전에는 잘 모를 때 그냥 9시간을 직접 빼거나 더하는 식으로 날짜를 조정하곤 했지만

 

이제는 그래도 개념이 좀 박혀서 그런지 그런 무식한 방법 보다는 이렇게 

세련된 방법을 통해 날짜시간을 조절하게 된 것 같다. 

 

이 버그를 해결하면서 DTO도 좀 더 보완할 수 있었으니 어찌보면 일석이조의 경험을 얻을 수 있는 문제가 아니었나 싶다.

 

오류 수정

알고보니 local에선 잘 되는데 

RDS를 바라보게 해서 생긴 오류였다.

 

실제로 다시 local DB를 바라보게 했더니 정상 작동 되었다.

그니까 RDS 쓰기 전까진 잘 됐으니 이제 발견했지.. 

 

아무튼 해결 방법은 RDS에 한국 시간 timezone을 적용시켜줘야 한다는 부분인데

 

https://programforlife.tistory.com/52

 

[AWS] RDS 시간 설정 하기 (Timezone 변경)

RDS 시간 설정 하기 AWS에서 생성한 RDS를 사용 중에, 시간 로그를 남겨야 하는 상황이 생겼습니다. 예를 들어, 미세먼지량을 측정해 데이터베이스에 저장하는데 해당 측정값이 언제 측정된 것인지

programforlife.tistory.com

위 블로그에 아주 친절히 나와있으니 이대로 따라하기만 하면 해결된다.

 

오류 수정 2

아니다 RDS의 잘못은 없었고 오히려 timezone 변경 없이 그대로 UTC를 유지해야 하며

내 코드의 문제였다.

 

https://4sii.tistory.com/467

 

3월16일 - MySQL, TypeORM, RDS timezone 문제 [해결]

해결 전 3월 16일 11시 51분에 schedule은 3월 16일 13시로 저장 local schedule, createdAt 둘 다 값 그대로 들어갔다. RDS schedule은 값 그대로, createdAt은 9시간 마이너스된 값이 들어감 local schedule, createdAt 각각

4sii.tistory.com

여기에 따로 정리 완료

728x90