티스토리 뷰
이 글은 Golang이라기 보다는 Postgres 이야기이다.
개요
Postgres는 timestamp, timestamptz 라는 데이터베이스 타입을 제공한다.
두 타입의 차이를 Golang과 bun 패키지를 이용해 확인해본다.
TL;DR
- 두 타입은 저장시의 표현방법의 차이이지 담고있는 절대시간의 값은 같다.
- timestamptz 타입은 Postgres 서버 내부에 설정되어 있는 timezone 설정에 따라 저장이 된다.
- 나의 선택은 timestamp를 사용하여 항상 UTC 타임으로 저장하며, 사용자에게 이를 보여주는 애플리케이션에서 사용자의 컴퓨터 timezone에 맞게 변환하여 보여주도록 하는 것이다.(다른 분들의 선택, 모범 답안이 궁금하다.)
준비작업: macOS에 Postgres 설치하기
다양한 옵션이 있는데 이거 간단해보인다. https://postgresapp.com/
클라이언트 앱도 하나 설치함 https://eggerapps.at/postico2/
실행과 동시에 이렇게 데이터베이스 서버가 생긴다
테스트용 테이블을 만들었다.
코드로 확인해보자
GitHub code: https://github.com/nicewook/bun-orm-study/blob/main/compare-timestamp/main.go
입력후 저장 값 확인
현재 시간을 집어넣으려 준비해둔다.
TStamp, TStamptz 두 필드 모두 +0900 KST 이다.
// prepare data
ctime := time.Now()
name := "test1"
myTime := MyTime{
Name: name,
TStamp: ctime,
TStampTZ: ctime,
}
printTime(myTime)
// timestamp: 2022-12-18 11:14:42.443372 +0900 KST m=+0.003532209
// timestamptz: 2022-12-18 11:14:42.443372 +0900 KST m=+0.003532209
하지만 데이터베이스에 INSERT 한 다음 가져와 보면
TStamp는 UTC 시간으로 변환이 되어 있는 것을 알 수 있다.
if _, err := db.NewInsert().Model(&myTime).
Where("name = ?", name).
Exec(context.Background()); err != nil {
fmt.Println(err)
return
}
if err := db.NewSelect().Model(&myTime).Scan(context.Background()); err != nil {
fmt.Println(err)
}
printTime(myTime)
// timestamp: 2022-12-18 01:41:49.921354 +0000 UTC
// timestamptz: 2022-12-18 10:41:49.921354 +0900 KST
특정 timezone 정보를 가진 값을 입력후 저장 값 확인
데이터베이스의 timezone 설정을 확인해보면 "Asia/Seoul" 이다.
// check timezone in Postgres
var tz string
db.NewRaw("SHOW TIMEZONE").Scan(context.TODO(), &tz)
fmt.Println("current timezone:", tz)
fmt.Println("---")
// current timezone: Asia/Seoul
현재 시간을 "Asia/Lolkata" timezone 값으로 변경해서 준비. +0530 IS로 되어 있다.
// location test
locat, _ := time.LoadLocation("Asia/Kolkata")
ctime = time.Now().In(locat)
locatName := "test2"
myTime = MyTime{
Name: locatName,
TStamp: ctime,
TStampTZ: ctime,
}
fmt.Printf("Asia/Kolkata:%s\n", ctime)
// Asia/Kolkata:2022-12-18 07:44:42.468642 +0530 IST
데이터베이스에 INSERT 후 가져와보자
- TStamp 필드에는 UTC로 변환하여 05:30 시간을 뺀 02:09:21이 되어 있고
- TStampTZ 필드에는 03:30 을 추가하여 한국시간으로 맞춘 11:09:21이 되어 있다.
if _, err := db.NewInsert().
Model(&myTime).
Exec(context.Background()); err != nil {
fmt.Println(err)
}
if err := db.NewSelect().Model(&myTime).
Where("name = ?", locatName).
Scan(context.Background()); err != nil {
fmt.Println(err)
}
printTime(myTime)
// timestamp: 2022-12-18 02:09:21.439701 +0000 UTC
// timestamptz: 2022-12-18 11:09:21.439701 +0900 KST
반응형
'golang' 카테고리의 다른 글
Golang: HTTP 클라이언트의 연결 관리(1) (0) | 2023.05.14 |
---|---|
Golang: embed한 파일을 API 요청에 회신해주기 (0) | 2023.01.04 |
Golang: go get으로 패키지를 최신으로 업데이트 하는 법 (0) | 2022.12.15 |
Golang ORM - Bun 삽질 이야기 - Automatic timestamp (0) | 2022.12.10 |
Golang ORM - Bun 삽질 이야기 - Query building (0) | 2022.12.10 |
반응형
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- github
- 독서후기
- 오블완
- solid
- folklore
- clean agile
- 체호프
- intellij
- websocket
- 노션
- Bug
- 제이펍
- 클린 애자일
- 영화
- ChatGPT
- OpenAI
- Shortcut
- notion
- 2023
- bun
- API
- go
- 인텔리제이
- 잡학툰
- agile
- 독서
- strange
- Gin
- 티스토리챌린지
- golang
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함