요약
| 항목 | DATETIME | TIMESTAMP |
| 데이터 타입 | 날짜와 시간을 달력과 시계에서 보이는 그대로 문자열로 표시하여 저장 | 날짜와 시간을 정확하게 절대적인 시점으로 표현하여 저장 |
| 의미 | 단순히 그레고리력의 날짜와 시간을 문자열 형태로 저장하는 것. | 단 하나의 '절대 시점'을 정의하기 위해 두 가지 개념이 적용됨. 1) 절대적인 시점을 나타내려면 특정 시점으로부터 경과된 시간을 계산해야 함. 2) 특정 시점의 시간대도 고정되어야 함. (그게 UTC) |
| 시간대(Time zone) 변환 | 시간대 정보 자체가 없기 때문에 해당 값만으로는 어느 시간대의 로컬 시간인지 알 수 없음 ⇒ 그래서 해당 값만으로는 다른 시간대의 로컬 시간으로 정확하게 변환할 수도 없음. 이 값을 의미 있는 시점으로 만들려면, 사용자가 별도의 시간대 정보를 수동으로 제공해야 함. | UTC를 기준으로 하는 절대적인 시점이므로 ⇒ UTC를 기반으로 모든 시간대(Time zone)의 로컬 시간으로 정확하게 변환할 수 있음. |
| 저장 범위 | DBMS마다 다름 MySQL (1000-01-01 00:00:00 ~ 9999-12-31) PostgreSQL (DATETIME이라는 이름의 타입은 없고, timestamp [without time zone] 가 그 역할을 함. => 4713 BC ~ 294276 AD) |
DBMS마다 다름 MySQL (1970-01-01 00:00:01 ~ 2038-01-19 03:14:07) PostgreSQL (timestamp with time zone => 4713 BC ~ 294276 AD) |
- 2020-01-01 00:00:00 UTC
- 2019-12-31 19:00:00 America/New_York
- 2020-01-01 05:30:00 Asia/Kolkata
1. UTC와 시간대에 대해 자세히 알아보자.
1-1. UTC(Coordinated Universal Time)란?
: 전 세계에서 표준 시간으로 사용하는 협정 세계시.
- 전 세계에서 공통으로 사용하는 하나의 기준 시간(UTC+00:00)
- 특정 국가나 지역에 묶이지 않는 전 지구 공통 시간 기준이며, 각 지역 시간(Local Time)은 이 UTC를 기준으로 몇 시간 앞서는지/뒤지는지(offset)로 정의된다.
▶ 영국 (GMT)은 UTC +0 (=기준점)
▶ 한국 (KST)은 UTC +9 → UTC 기준보다 9시간 빠름
▶ 뉴욕 (EST)은 UTC -5 → UTC 기준보다 5시간 느림
- UTC(협정 세계시)의 기준점은 경도 0도선이며, 이는 영국 런던의 그리니치 천문대를 통과하는 본초 자오선에 해당한다. 이 기준점을 기준으로 동쪽으로 갈수록 더하고 서쪽으로 갈수록 빼는 형식(예: 한국은 UTC+9)으로 표시
- 왜 중요할까? 컴퓨터 시스템, 서버, 데이터베이스는 전 세계에 분산되어 있기 때문에, 각기 다른 시간대를 사용하는 서버끼리 시간을 비교하려면 공통 기준이 필요함. 이 공통 기준이 바로 UTC다.
2-2. 시간대(time zone)란?
: 지구를 몇 개의 구역으로 나누어, 같은 구역 안에서는 같은 ‘표준시’를 쓰도록 정해 놓은 제도
- 시간대(time zone)는 특정 국가/도시 등 지역에 연결된 규칙
- 각 시간대는 "UTC에서 몇 시간 차이 나는지"로 정의된다. 예를 들어,
▶ 한국 표준시(KST)는 UTC+09:00
▶ 일본 표준시(JST)도 UTC+09:00
▶ 뉴욕의 동부 표준시(EST)는 UTC-05:00
- 쉽게 말해 “어느 나라 사람들이 일상에서 몇 시라고 부를 것인가”를 정해놓은 규칙 세트라고 보면 된다.
- 우리가 일상에서 쓰는 ‘현재 시각(오전 9시, 오후 3시 등)’은 UTC 그 자체가 아니라, "내가 있는 지역의 시간대 규칙(UTC+오프셋, 써머타임 등)을 적용한 결과"이다.
[정리]
UTC가 전 세계가 공유하는 하나의 기준 시계라면,
시간대는 “그 기준 시계를 각 지역에서 어떻게 읽을 것인지”를 정해 놓은 규칙.
3. DATETIME
- 단순하게 "YYYY-MM-DD HH:MM:SS" 문자열 같은 값을 저장한다고 생각하면 된다.
- 즉 시간대(timezone) 정보가 전혀 없는 것.
- DB는 “이 값이 KST인지, UTC인지, 뉴욕 시간인지” 모름.
예를 들어 아래와 같이 DATETIME 타입으로 저장된 날짜가 있다고 하자.
'2025-11-18 10:00:00'
DATETIME으로 저장되어 있기 때문에 시간대 정보가 없으니까, 이게 “KST 기준 10시”인지 “UTC 기준 10시”인지 데이터만으로는 알 수 없음. (단 문서에 따로 타임존에 대한 정보를 기록해두거나, 사람이 기억해 두어야 함. 데이터가 아닌 문서나 사람의 기억에 의존해야 함.)
4. TIMESTAMP
TIMESTAMP는
→ 데이터를 저장할 때는 UTC(세계표준시)기준의 시점으로 저장하고,
→ 데이터를 불러올 때는 사용자(클라이언트/세션)의 로컬 시간대(timezone) 설정에 맞게 변환할 수 있다.
예를 들어:
- 한국 시간(UTC+9)으로 "KST 2025-07-17 12:00:00"을 넣으면,
- MySQL이 내부적으로 "UTC 2025-07-17 03:00:00"로 바꿔서 저장하고,
- 다시 한국에서 조회하면 시간대 설정에 맞춰 다시 12:00:00으로 변환해서 보여준다.
그래서 시간대가 중요한 경우, 로그 데이터, 이벤트 시각을 저장할 때 적절하다. 또한 글로벌 서비스를 운영할 때 매우 유용하다. 전 세계 사용자 이벤트를 하나의 기준(UTC)으로 통일할 수 있기 때문에.
만약 글로벌 서비스에서 DATETIME을 사용하여 날짜를 저장하면 -> 한국에서 회원가입을 09:00에 한 사용자를 미국에서도 그대로 09:00에 한 것처럼 보일 수 있다. 따라서 TIMESTAMP를 사용하여 날짜를 저장하는 것이 좋다.
5. 언제 어떤 타입을 써야 할까?
| 상황 | 추천 타입 | 이유 |
| 회원가입일, 수정일, 로그 저장 | TIMESTAMP | UTC 기준 기록 → 서버 간 시간 비교 정확 |
| 생일, 마감일, 이벤트 시간 | DATETIME | 시간대 상관없이 입력 그대로 유지 |
| 글로벌 서비스 운영 | TIMESTAMP | 시간대 자동 처리 가능 |
| MySQL 5.x 사용 + 미래 날짜 저장 | DATETIME | TIMESTAMP는 2038년까지 제한 |
TIMESTAMP (UTC 기준 & 시간대) 를 쓰면 좋은 경우
- 실제로 일어난 순간이 언제인지, "언제 발생했는지"가 중요한 데이터 (로그, 생성일, 수정일, 회원 가입일 등)
- 전 세계 사용자, 시간 비교/정렬이 중요한 경우
DATETIME 을 쓰면 좋은 경우
- 사람이 느끼는 ‘달력의 날짜/시간’ 자체가 중요한 데이터
(예: “회의는 3월 1일 9시(한국 시간)”, “영업일 마감일은 4월 30일 23:59(한국)” 같이 특정 시간대와 붙어서 의미가 있는 값)
- 단 DATETIME으로 저장하되 “이 값은 항상 KST 기준이다” 같은 비즈니스 규칙을 명시해야 한다. DATETIME을 쓰면 시간대 없이 캘린더 값만 저장하는 셈이므로 UTC인지, KST인지 구분이 안 되기 때문에, “우리는 무조건 이 필드는 UTC로 저장한다고 규칙으로 정한다” 또는 “이 필드는 항상 KST 기준 값이다” 등 명확한 약속이 필요하다.
6. 실무 예시
6-1. 테이블 만들 때 (MySQL 기준)
CREATE TABLE users (id INT PRIMARY KEY
, email VARCHAR(255)
, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
, birthday DATETIME
);
- created_at: 자동으로 가입 시각 기록 (서버 시간 기준)
- birthday: 사용자가 입력한 생일은 시간대와 무관하게 그대로 저장
6-2. TIMESTAMP타입으로 저장된 날짜 데이터(UTC) → 로컬 시간대(KST)로 변경하는 방법
특정 DBMS는 로컬 시간대에 맞춰 자동으로 변환해 주기도 하지만, BigQuery처럼 자동 변환이 안 되는 환경이 존재하기 때문에 항상 DBMS의 타임존 처리 방식을 확인한 후 쿼리를 작성하는 것이 안전한다. 확인 후 자동 변환이 되지 않는다면, 쿼리에서 명시적으로 타임존 변환에 대해 작성해줘야 한다.
아래와 같이 UTC로 저장된 TIMESTAMP 타입의 UTC로 저장된 날짜 데이터를 KST(대한민국 시간, UTC+9) 기준으로 조회하거나 표시하려면 명시적으로 변환해주어야 한다. 예를 들어 BigQuery라면, 다음처럼 DATETIME(TIMESTAMP, TIME_ZONE) 함수로 변환할 수 있다.
<BigQuery에서 UTC → KST 변환하는 방법>
SELECT timestamp_column
, DATETIME(TIMESTAMP(timestamp_column), "Asia/Seoul") AS timestamp_kst
FROM your_table;
▶ timestamp_column → UTC 기준 시간
▶ "Asia/Seoul" → KST로 변환할 지역
▶ timestamp_kst → 사람이 보기 쉬운 KST 기준 시간 (타임존 변환하면서 데이터 타입도 DATETIME 으로 변환되었음!)
근데 왜 변환해야 할까?
1. 로컬 시간대로 변환하지 않으면 날짜 단위 조회 시 혼란이 발생할 수 있기 때문에, 정확한 날짜 필터링을 위해 바꾸는 게 좋다.
2. 한국 기준 리포트나 로그 분석 시, 현지 시간 기준으로 맞춰야 해석이 쉽기 때문에, 사용자 편의를 위해 바꾸는 게 좋다.
3. 만약 DATETIME 형식의 날짜 데이터 컬럼을 갖고 있다면, 해당 컬럼은 보통 해당 로컬 시간대(Asia/Seoul)로 작성되었을 것이므로, TIMESTAMP로 저장된 컬럼도 KST도 맞춰야 비교가 가능하기 때문에, 일관성 확보를 위해 바꾸는 게 좋다.
'데이터 처리 도구 > SQL' 카테고리의 다른 글
| 인덱스 알고리즘 (B-Tree, Hash) (0) | 2025.08.12 |
|---|---|
| SQL 성능 향상을 위한 공부: 1-4) 실행 계획을 확인하는 방법 (0) | 2025.07.21 |
| SQL 성능 향상을 위한 공부: 1-3) 쿼리 평가엔진에 대하여 (0) | 2025.07.11 |
| SQL 성능 향상을 위한 공부: 1-2) DBMS와 기억장치의 관계 (0) | 2025.07.02 |
| SQL 성능 향상을 위한 공부: 1-1) DBMS 아키텍처 이해하기 (0) | 2025.07.01 |