해당 글에서는 PostgreSQL + Docker 환경에서 TimeZone을 지정했던 방법에 대해서 공유합니다.
![]()
1) Coordinated Universal Time (UTC) / TimeZone
1. Coordinated Universal Time (UTC)
💡 Coordinated Universal Time (UTC)
- 전 세계 시간대 설정의 기준이 되는 가장 정확한 원자시 기반의 시간 표준입니다.
- 본초 자오선(경도 0도)을 기준으로 하며, 서머타임(일광 절약 시간제)을 적용하지 않아 연중 일정한 시간을 유지합니다.
- 한국의 경우는 타임존(KST)을 가지며, UTC 대비 9시간이 늦은 UTC+9를 가집니다.
https://en.wikipedia.org/wiki/Coordinated_Universal_Time

2. TimeZone
💡 TimeZone
- 타임존(Time Zone)은 지구를 경도 기준으로 나눈 시간 구역을 의미합니다.
- 지구는 24시간에 360° 자전하므로, 경도 15°마다 1시간 차이가 발생합니다. 이를 기반으로 전 세계를 구역으로 나눠 같은 구역 내에서는 동일한 시간을 사용하도록 약속한 것이 타임존입니다.
- 예를 들어서 절대적인 시간 기준점이 0이라고 하면, TimeZone은 UTC에서 얼마나 떨어져 있는지를 오프셋을 의미합니다.
- 한국의 경우 UTC를 기준으로 +9 거리를 가지기에 UTC Offset +9입니다.

Time Zone Map
Current local times around the world, including (DST) changes.
www.timeanddate.com
| 지역 | 국가/도시 | UTC | 오프셋 현지시간(UTC 기준) | 비고 |
| 아시아 | 🇰🇷 서울 (대한민국) | UTC+9 | UTC + 9시간 | KST |
| 🇯🇵 도쿄 (일본) | UTC+9 | UTC + 9시간 | JST | |
| 🇨🇳 베이징 (중국) | UTC+8 | UTC + 8시간 | CST | |
| 🇭🇰 홍콩 | UTC+8 | UTC + 8시간 | HKT | |
| 🇸🇬 싱가포르 | UTC+8 | UTC + 8시간 | SGT | |
| 🇹🇭 방콕 (태국) | UTC+7 | UTC + 7시간 | ICT | |
| 🇻🇳 하노이 (베트남) | UTC+7 | UTC + 7시간 | ICT | |
| 🇮🇳 뭄바이 (인도) | UTC+5:30 | UTC + 5시간 30분 | IST | |
| 🇦🇪 두바이 (UAE) | UTC+4 | UTC + 4시간 | GST | |
| 오세아니아 | 🇦🇺 시드니 (호주) | UTC+10 / +11 | UTC + 10~11시간 | AEST / AEDT (서머타임) |
| 유럽 | 🇬🇧 런던 (영국) | UTC+0 / +1 | UTC ± 0~1시간 | GMT / BST (서머타임) |
| 🇩🇪 베를린 (독일) | UTC+1 / +2 | UTC + 1~2시간 | CET / CEST (서머타임) | |
| 🇫🇷 파리 (프랑스) | UTC+1 / +2 | UTC + 1~2시간 | CET / CEST (서머타임) | |
| 🇷🇺 모스크바 (러시아) | UTC+3 | UTC + 3시간 | MSK (서머타임 없음) | |
| 아프리카 | 🇿🇦 요하네스버그 (남아공) | UTC+2 | UTC + 2시간 | SAST |
| 🇪🇬 카이로 (이집트) | UTC+2 / +3 | UTC + 2~3시간 | EET / EEST (서머타임) | |
| 아메리카 | 🇺🇸 뉴욕 (미국 동부) | UTC-5 / -4 | UTC - 5~4시간 | EST / EDT (서머타임) |
| 🇺🇸 시카고 (미국 중부) | UTC-6 / -5 | UTC - 6~5시간 | CST / CDT (서머타임) | |
| 🇺🇸 LA (미국 서부) | UTC-8 / -7 | UTC - 8~7시간 | PST / PDT (서머타임) | |
| 🇨🇦 밴쿠버 (캐나다) | UTC-8 / -7 | UTC - 8~7시간 | PST / PDT (서머타임) | |
| 🇲🇽 멕시코시티 (멕시코) | UTC-6 / -5 | UTC - 6~5시간 | CST / CDT (서머타임) | |
| 🇧🇷 상파울루 (브라질) | UTC-3 | UTC - 3시간 | BRT |
[ 더 알아보기 ]
💡 오프셋(Offset) 이란?
- 기준점으로부터 얼마나 떨어져 있는지를 나타내는 차이값을 의미합니다.
- 타임존에서만 쓰는 말이 아니라, 전반적으로 ”기준에서 얼마나 벗어나 있냐"를 표현할 때 쓰는 용어를 의미합니다
2) 문제점
💡 문제점
- 데이터베이스 내에서 now() 내장 함수를 통해서, 현재 시간을 DB에 저장 중에 있습니다.
- 그런데 UTC 시간으로 저장으로 되기에 05:56분과 같은 시간으로 저장이 되었습니다. 이를 대한민국 시간에 맞게 수정하기 위해서, TimeZone을 지정합니다.

3) 해결방법
💡 해결방법
- 위에서 UTC로 지정이 되어 있는 시간을 각각 국가(Asia/Seoul)에 맞게 설정을 하여서 now() 함수를 사용하더라도 TimeZone에 맞는 시간이 나오도록 하는 방식을 사용합니다.
| 레이어 | 설정 위치 | 설명 | 예시 |
| JDBC TimeZone | application.yml | Java 앱이 DB에 연결할 때 사용하는 타임존. 명시 안 하면 JVM TimeZone을 따라감 | - hibernate.jdbc.time_zone: UTC - options=-c%20timezone%3DAsia/Seoul |
| OS TimeZone | 서버 운영체제 | 컨테이너/서버 운영체제의 기본 타임존. 다른 레이어의 기본값이 됨 | timedatectl set-timezone UTC |
| Docker | db 컨테이너 OS 타임존 설정. 명시 안 하면 Docker 호스트 OS를 따라감 | db: TZ=Asia/Seoul | |
| 서버 TimeZone | postgresql.conf | PostgreSQL 서버 전체에 적용되는 타임존. postgresql.conf로 설정하거나 실행 시 -c 옵션으로 지정 | timezone = 'UTC' |
| Docker | postgresql.conf 없이 서버 시작 시 -c 옵션으로 바로 지정 | command: postgres -c timezone=Asia/Seoul | |
| DB TimeZone | DB 세션/전역 | 특정 DB 또는 세션 단위로 적용되는 타임존. 서버 TimeZone보다 우선순위가 높음 | SET timezone = 'UTC' 또는 ALTER DATABASE dbname SET timezone = 'UTC' |
| JVM TimeZone | Java 프로세스 | Java 프로세스 전체에 적용되는 타임존. JDBC TimeZone 미설정 시 이걸 따라감 | -Duser.timezone=UTC 또는 TimeZone.setDefault(...) |
| Docker | api 컨테이너의 JVM 타임존 설정. Spring Boot 포함 Java 전체에 적용됨 | api: TZ=Asia/Seoul | |
| psql 클라이언트 TimeZone | 환경변수 | psql 터미널 접속 시 사용하는 타임존. 서버 TimeZone과 별개로 클라이언트 표시에만 영향 | PGTZ=Asia/Seoul |
1. JDBC TimeZone 지정
💡 JDBC TimeZone 지정
- Java 내에서 DateTime, TimeStamp의 클래스의 경우는 컬럼 타입의 저장 시 타임존의 변화가 일어나는데, JDBC 드라이버에서 어떤 타임존 기준으로 변환할지 모르면, JVM 기본 타임존을 사용합니다.
- Java에서 시간 데이터를 보내거나 받을 때, JDBC 드라이버가 KST(+9) 기준으로 변환해서 데이터베이스와 주고받겠다는 뜻입니다.
1.1. MySQL
💡 MySQL
- serverTimezone=Asia/Seoul을 파라미터로 전달하는 방식으로 사용이 됨.
# application.yml
spring:
datasource:
url: jdbc:mysql://xxxxx:35432/dbname?serverTimezone=Asia/Seoul&useUnicode=true&characterEncoding=UTF-8
1.2. PostgreSQL
💡 PostgreSQL
- 아래에서는 인코딩 된 상태로 ‘options=-c%20timezone%3DAsia/Seoul’를 적용하였습니다.
- 이 URL을 디코딩하게 되면 options=-c timezone=Asia/Seoul로 출력이 됩니다.
# application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/dbname?options=-c%20timezone%3DAsia/Seoul
Initializing the Driver | pgJDBC
Initializing the Driver This section describes how to load and initialize the JDBC driver in your programs. Importing JDBC Any source file that uses JDBC needs to import the java.sql package, using: NOTE You should not import the org.postgresql package unl
jdbc.postgresql.org
[참고]
- 실제로 해당 옵션을 추가하더라도 수행하지 않았다는 글이 있습니다.
- 이는 pgJDBC 드라이버가 연결 시 JVM 타임존이 강제로 덮어버린다는 이슈가 있습니다.
property "options" "-c timezone=America/New_York" does not seem to work · Issue #1626 · pgjdbc/pgjdbc
I'm submitting a ... bug report feature request Describe the issue I'm passing the property options with the value -c timezone=America/New_York to the connection. The timezone for my session is not...
github.com
2. PostgreSQL 타임존 지정
💡 PostgreSQL 타임존 지정
- PostgreSQL 세션/서버 타임존을 지정을 합니다. 이를 지정하지 않으면, 서버 OS 타임존을 따라갑니다.
2.1. 현재 타임존 확인
💡 현재 타임존 확인
- 지정된 타임존의 시간을 확인하고, 현재 NOW() 함수와 타임존을 지정한 시간을 비교하여 확인합니다.
SHOW timezone;
SELECT NOW(), NOW() AT TIME ZONE 'Asia/Seoul';

2.2. 타임존 시간 지정
💡 타임존 시간 지정
- 세션 레벨, DB 레벨(영구), 유저 레벨(영구)에서 수행하여 다시 조회를 하면, 타임존이 반영된 NOW()가 수행이 되었습니다.
-- 세션 레벨 (둘 다 동일)
SET TIME ZONE 'Asia/Seoul'; -- SQL 표준 방식
SET timezone TO 'Asia/Seoul'; -- PostgreSQL 방식
-- DB 레벨 (영구)
ALTER DATABASE dbname SET timezone TO 'Asia/Seoul';
-- 유저 레벨 (영구)
ALTER USER username SET timezone TO 'Asia/Seoul';
3. Docker 내에 TimeZone 지정
💡 Docker 내에 TimeZone 지정
- 컨테이너 배포 시, 빌드된 이미지를 컨테이너화 하는 과정에서 설정값을 적용합니다.
- postgresql.conf 설정 파일 내에 지정하는 것이 베스트이지만, 배포 시에 설정값을 포함하여서 배포를 합니다.
- 아래와 같이 docker compose 과정에서 compose.yaml 파일을 수정하여 TimeZone을 지정합니다.
services:
db:
image: postgres:17.9
container_name: xxxxx-db
command: postgres -c timezone=Asia/Seoul # PostgreSQL 서버 타임존 강제 지정
environment:
- TZ=Asia/Seoul # 컨테이너 OS 타임존
- PGTZ=Asia/Seoul # psql 클라이언트 타임존
ports:
- "5432:5432"
env_file:
- ./env/.env.db
volumes:
- pgdata:/var/lib/postgresql/data
restart: always
api:
image: xxxxx
container_name: xxxxx-api
depends_on:
- db
restart: unless-stopped
volumes:
- "./uploads:/uploads"
environment:
- TZ=Asia/Seoul # JVM 타임존 → Hibernate가 이걸 기준으로 저장
오늘도 감사합니다. 😀
'DB > 이론 및 문법' 카테고리의 다른 글
| [DB] PostgreSQL pgcrypto 이해하고 AES256 암복호화 활용 (0) | 2026.05.01 |
|---|---|
| [DB] 데이터베이스 시퀀스 번호 조회 및 변경 방법 : CURRVAL, NEXTVAL, SETVAL (0) | 2024.08.07 |
| [DB/MySQL] WITH ROLLUP, PIVOT 구조 및 활용방법 (0) | 2024.07.07 |
| [DB/MySQL] SQL내에서 JSON 데이터 활용 방법 : JSON 주요 함수 및 사용 예시 (1) | 2024.06.30 |
| [DB/MySQL] WITH ~ [RECURSIVE] CTE(Common Table Expression) 이해하기 (0) | 2024.06.25 |
