데이터 처리/SQL

SQL에서 날짜 데이터 타입 차이 (DATETIME vs. TIMESTAMP)

yourhm 2025. 7. 17. 22:04

요약

항목 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도 맞춰야 비교가 가능하기 때문에, 일관성 확보를 위해 바꾸는 게 좋다.