[SW공학] 웹 개발 시간대(Timezone) 완벽 정복: UTC 기준 설계와 흔한 함정들
웹 개발 시간대(Timezone) 완벽 정복: UTC 기준 설계와 흔한 함정들
웹 애플리케이션 개발에서 시간대(Timezone) 처리는 흔히 어려움을 겪는 부분이다. "내 PC에서는 잘 나왔는데 서버 시간은 왜 다르지?", "오후 2시 데이터를 넣었는데 API 결과는 왜 이럴까?"와 같은 문제는 많은 개발자가 마주하는 현실이다. 특히 데이터베이스, 백엔드 서버, 프론트엔드 클라이언트 등 여러 컴포넌트가 얽힌 분산 환경에서는 명확한 시간대 전략 없이는 혼란과 버그가 발생하기 쉽다.
이 글의 목적은 이러한 시간대 문제를 예방하고, 안정적이고 예측 가능한 시스템을 구축하기 위한 모범 사례, 특히 UTC(협정 세계시)를 표준으로 사용하는 전략을 상세히 설명하는 것이다.
시간대는 왜 이리 까다로운가?
- 지리적 다양성: 사용자와 서버는 전 세계 각기 다른 시간대에 위치할 수 있다.
- 서머타임 (Daylight Saving Time): 특정 지역의 계절적 시간 변경은 계산을 복잡하게 만든다.
- 모호성: '오후 2시'라는 정보만으로는 어느 지역 기준인지 알 수 없으므로, 시간대 또는 UTC 오프셋 정보가 필수적이다.
- 일관성 부재: 명확한 전략이 없다면 각 컴포넌트가 시간을 다르게 해석하여 데이터 불일치를 유발한다.
황금률: UTC를 표준으로 삼아야 한다!
이런 혼란을 피하는 가장 효과적인 방법은 시스템 전체의 기준 시간을 UTC로 통일하는 것이다. 그 원칙은 다음과 같다.
"시스템 내부 처리와 컴포넌트 간 통신은 UTC로, 사용자에게 보여줄 때만 로컬 시간으로!"
UTC는 국제 표준시이며 시간대 변환의 기준점이다. 모든 시간 정보를 UTC로 관리하면 다음과 같은 장점이 있다.
- 명확성: 시간 표현이 모호하지 않으며 전 세계적으로 동일한 시점을 나타낸다.
- 단순성: 시간대 변환 로직이 단순해지고 계산 오류가 줄어든다.
- 일관성: 시스템의 모든 부분에서 시간 데이터를 일관되게 처리할 수 있다.
이상적인 시간대 설계: 계층별 접근법
UTC 중심 전략을 각 시스템 계층에 적용하는 방법은 다음과 같다.
- 데이터베이스 (저장 계층)
- 권장 방식: 모든 날짜/시간 데이터를 UTC 기준으로 저장하는 것이다.
- 구현:
- MySQL:
DATETIME
대신TIMESTAMP
타입을 사용한다.TIMESTAMP
는 내부적으로 UTC로 저장하고, 연결 설정에 따라 자동으로 변환된다. - PostgreSQL:
TIMESTAMP WITH TIME ZONE
(TIMESTAMPTZ) 타입을 사용한다. 이 또한 내부적으로 UTC로 저장한다.
- MySQL:
- 예시: 글로벌 쇼핑몰에서 주문 시각을 정확히 기록해야 한다고 가정하자. 고객이나 서버 위치에 상관없이 일관된 타임라인을 확보하려면, 주문 시간을 UTC 기준
TIMESTAMP
타입으로 저장하는 것이 최선이다.
- 백엔드 서버 (애플리케이션 로직)
- 권장 방식: 백엔드 서버의 기본 시간대를 UTC로 설정하고 운영하는 것이다. (예: JVM 옵션
-Duser.timezone=UTC
) - 구현: 내부적으로 날짜/시간을 처리할 때는 UTC 기준 객체(Java
Instant
,ZonedDateTime
등)를 사용해야 한다. 외부에서 로컬 시간이 입력되면 가능한 한 빨리 UTC로 변환하여 처리한다. - 예시: 이벤트 예약 시스템에서 사용자가 "오전 10시" 예약을 요청했다. 서버가 UTC 기준이라면, 이 시간이 어느 지역의 오전 10시인지 명확히 하거나(입력 시 시간대 명시), 서버가 컨텍스트에 따라 UTC로 변환한 후 내부 처리 및 저장을 수행해야 한다.
- 권장 방식: 백엔드 서버의 기본 시간대를 UTC로 설정하고 운영하는 것이다. (예: JVM 옵션
- API 통신 (데이터 교환)
- 권장 방식: API를 통해 데이터를 주고받을 때는 항상 UTC 기준으로 통신하는 것이다.
- 구현:
- ISO 8601 UTC 문자열 (권장):
YYYY-MM-DDTHH:mm:ss.sssZ
형식 (예:2025-10-26T13:45:30Z
). 사람이 읽기 쉽고 기계도 파싱하기 좋으며, 'Z'가 UTC임을 명확히 한다. - Unix 타임스탬프 (숫자): 초 또는 밀리초 단위 숫자 (예:
1761505530
또는1761505530000
). 플랫폼 독립적이며 기계 처리가 용이하다.
- ISO 8601 UTC 문자열 (권장):
- 예시: 항공권 예매 앱이 서버 API로부터 출발 시각 정보를 받는다.
2025-12-25T22:00:00Z
와 같이 UTC로 명시된 정보를 받아야 하며, 단순히22:00
이라는 정보만으로는 혼란이 발생한다.
- 프론트엔드 (사용자 인터페이스)
- 권장 방식: 사용자에게 시간을 보여줄 때는 사용자의 로컬 시간대로 변환하여 표시하는 것이다.
- 구현: API로부터 받은 UTC 데이터를 브라우저의 내장 기능(
Intl.DateTimeFormat
)이나 라이브러리(date-fns
,Day.js
등)를 사용하여 사용자의 현재 시간대로 변환하고 적절한 형식으로 포맷한다. - 예시: 항공권 예매 앱이 API로부터
2025-12-25T22:00:00Z
정보를 받았다. 사용자의 기기 시간대가 한국(KST, UTC+9)이라면 "2025년 12월 26일 오전 7:00 출발"로 표시하고, 런던(GMT, UTC+0)이라면 "2025년 12월 25일 오후 10:00 출발"로 표시하는 것이 올바르다.
흔한 함정: 시간대 불일치 문제와 해결책
실제 개발 환경에서는 종종 문제가 발생한다. 가장 흔한 시나리오 중 하나는 다음과 같다.
- 상황:
- Node.js 기반의 배치 프로그램이 한국 시간(KST) 기준으로
2025-04-17 09:00:00
데이터를 생성하여 MySQLDATETIME
컬럼에 저장한다. - MySQL 데이터베이스 서버의 기본 시간대도 한국 시간(KST)이다.
- 별도의 API 서버(Java 기반)는 UTC 시간대 기준으로 운영된다. 이 서버가 DB의
DATETIME
값을 읽는다.
- Node.js 기반의 배치 프로그램이 한국 시간(KST) 기준으로
- 문제 발생: API 서버(UTC)가 DB에서
09:00:00
값을 읽을 때, DB 서버의 시간대가 KST라는 정보를 명시적으로 알지 못하면, 이 값을 자신의 기준인 UTC로 해석할 수 있다. 즉,2025-04-17 09:00:00 UTC
로 오해한다. - 결과: API는
09:00 UTC
에 해당하는 타임스탬프를 클라이언트로 보낸다. 한국에 있는 사용자의 브라우저는 이 타임스탬프를 KST로 변환하여2025-04-17 18:00:00
(09:00 UTC + 9시간)으로 표시한다. 사용자는 오전 9시 데이터를 기대했지만 오후 6시가 보이는 상황이 발생한다. - 해결책: 문제의 근원은 데이터를 읽는 쪽(API 서버)이 데이터 소스(DB)의 시간대를 잘못 해석한 것이다. 따라서 읽는 쪽에서 데이터 소스의 시간대를 명확히 인지하도록 설정해야 한다.
- Java/JDBC의 경우: 데이터베이스 연결 문자열(Connection String)에
serverTimezone=Asia/Seoul
(또는 실제 DB 시간대) 파라미터를 추가하는 것이 해결책이다. 이렇게 하면 API 서버는 DB에서 읽은DATETIME
값이 KST임을 인지하고 올바른 시점(이 경우00:00 UTC
)으로 해석하여 정확한 타임스탬프를 생성한다.
- Java/JDBC의 경우: 데이터베이스 연결 문자열(Connection String)에
제약 조건 하에서의 대처
만약 "DB 시간대는 절대 변경할 수 없다" 와 같은 제약 조건이 있다면, 여전히 UTC 중심 전략을 유지하되, 애플리케이션과 데이터베이스의 연결 설정(예: JDBC serverTimezone
)을 통해 그 간극을 메우는 것이 중요하다. 즉, 애플리케이션이 DB의 시간대를 인지하고 데이터를 읽어온 후, 내부적으로 최대한 빨리 UTC로 변환하여 처리하는 방식이 필요하다.
결론
시간대 처리는 웹 개발에서 까다롭지만 중요한 과제이다. UTC를 시스템의 표준 시간으로 삼고, 각 계층에서 시간대를 명확히 인지하고 변환하는 전략을 수립하는 것이 핵심이다. 특히, 서로 다른 시간대 설정을 가진 컴포넌트가 상호작용하는 지점에서의 시간대 해석 설정은 주의 깊게 검토해야 한다. 명확한 시간대 전략은 미래에 발생할 수많은 버그와 혼란을 예방하는 가장 확실한 방법이다.