일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Dinosaur
- nodejs
- MongoDB
- jest
- Queue
- cookie
- 게임
- JavaScript
- class
- flask
- Python
- TypeScript
- OCR
- 정렬
- MySQL
- Express
- 공룡게임
- Bull
- nestjs
- Sequelize
- 자료구조
- dfs
- AWS
- mongoose
- typeORM
- Nest.js
- react
- GIT
- game
- Today
- Total
포시코딩
3월15일 - TypeORM과 UTC Time zone 문제.. 인줄 알았으나 RDS 타임존 문제.. 인줄 알았으나 내 코드 문제 본문
개요
개발하다보면 날짜 시간 관련해서 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
위 블로그에 아주 친절히 나와있으니 이대로 따라하기만 하면 해결된다.
오류 수정 2
아니다 RDS의 잘못은 없었고 오히려 timezone 변경 없이 그대로 UTC를 유지해야 하며
내 코드의 문제였다.
여기에 따로 정리 완료
'TIL' 카테고리의 다른 글
3월20일 - Nest.js TypeORM get random row (0) | 2023.03.20 |
---|---|
3월16일 - MySQL, TypeORM, RDS timezone 문제 [해결] (0) | 2023.03.16 |
3월11일 - window.location.origin (0) | 2023.03.11 |
3월10일 - og 태그 (링크 미리보기) (0) | 2023.03.10 |
3월9일 - @nestjs/event-emitter (0) | 2023.03.10 |