2021-12-14 @이영훈
NestJS에서 DB에서 불러온 데이터의 타임존을 어떻게 처리하는 지 궁금했습니다.
시스템 환경의 타임존과 NestJS의 타임존이 있습니다.
docker로 타임존을 변경시켜 시스템 환경을 테스트해 보았습니다.
각각의 환경에 따라서 테스트해보고 관찰해보았던 내용을 기록으로 남깁니다.
Database
DB의 타임존은 UTC입니다
user 테이블이 존재하고 created_at 칼럼을 가지고 있습니다
첫번째 테스트
1.
테스트 환경
DB: UTC
Docker: Asia/Seoul
NestJS: Asia/Seoul
user.created_at: 2021-12-14 17:00:00
2.
로그 출력 결과
a.
user.created_at: 2021-12-14T08:00:00.000Z
b.
new Date(): 2021-12-14T04:09:09.646Z // 한국시간 13:09
두번째 테스트
1.
테스트 환경
DB Timezone: UTC
Docker Timezone: UTC
NestJS Timezone: UTC
# Docker에서 timezone이 변경되었는 지 확인하였습니다
docker run -it api-server date
# Tue Dec 14 04:25:16 UTC 2021
Bash
복사
2.
로그 출력 결과
a.
user.created_at: 2021-12-14T17:00:00.000Z
b.
new Date(): 2021-12-14T04:28:10.093Z // 한국시간 13:28
세번째 테스트
1.
테스트 환경
DB Timezone: UTC
Docker Timezone: Asia/Seoul
NestJS Timezone: UTC
# Docker에서 timezone을 확인했습니다
docker run -it starplay-api-dev date
# Tue Dec 14 13:47:33 KST 2021
Bash
복사
2.
로그 출력 결과
a.
user.created_at: 2021-12-14T17:00:00.000Z
b.
new Date(): 2021-12-14T04:30:38.396Z // 한국시간 13:30
결론
1.
node에서 new Date()는 UTC로 출력합니다 (UTC 시간대에서는 시각 뒤에 Z를 붙입니다)
2.
System timezone이 중요한 게 아니라 NestJS의 Timezone이 중요합니다
3.
TypeORM이 DB에서 시간을 가져와서 NestJS의 타임존으로 인식합니다
a.
[NestJS: Asia/Seoul] 2021-12-14 17:00:00 (KST로 인식) → 2021-12-14T08:00:00.000Z
b.
[NestJS: UTC] 2021-12-14 17:00:00 (UTC로 인식) → 2021-12-14T17:00:00.000Z
이유
connection option에서 timezone의 기본값이 'local'로 설정되어 있습니다.
그래서 위의 경우 NestJS의 타임존 설정이 Asia/Seoul 이었기 때문에 TypeORM에서 타임존(Asia/Seoul)을 읽어서 사용했습니다.
TypeORM 설정을 변경하는 코드입니다.
import { createConnection } from 'typeorm';
export const databaseProviders = [
{
provide: 'DATABASE_CONNECTION',
useFactory: async () => await createConnection({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [
__dirname + '/../**/*.entity{.ts,.js}',
],
synchronize: true,
timezone: 'local', // 'local', 'Z', '+HH:MM', '-HH:MM' 등으로 적절히 변경해주세요. 기본값은 'local' 입니다
}),
},
];
TypeScript
복사
https://docs.nestjs.com/recipes/sql-typeorm#getting-started