시간은 그것을 올바르게 처리하는 소프트웨어를 작성하기 전까지는 단순해 보입니다. "오후 3시"에 예정된 이벤트는 도쿄, 런던, 뉴욕에서 각각 다른 시간을 의미합니다. 일광 절약 시간제는 시계를 앞뒤로 조정합니다 — 하지만 모든 곳에서가 아니며, 같은 날짜도 아닙니다. 로컬 환경에서는 올바르게 보이는 타임스탬프가 서버가 다른 시간대에 있어서 프로덕션에서 깨지는 일이 발생합니다.
시간대는 소프트웨어 개발에서 가장 확실하게 혼란을 일으키는 주제 중 하나입니다. 이 글에서는 시간대의 작동 방식, 복잡성의 원인, 가장 일반적인 실수를 피하는 방법을 설명합니다.
시간대가 존재하는 이유
지구는 24시간에 360도를 회전합니다. 즉, 태양이 가장 높은 지점에 있는 순간이 경도에 따라 다릅니다. 19세기 이전에는 모든 도시가 지방 태양시를 사용했습니다 — 정오는 태양이 머리 위에 있을 때였습니다. 철도가 먼 도시를 연결하고 열차 시간표에 통일된 시계가 필요하게 될 때까지 이것으로 충분했습니다.
1884년, 25개국 대표가 워싱턴 D.C.의 국제 자오선 회의에 모여, 영국 그리니치를 지나는 본초 자오선(경도 0도)을 기준으로 세계를 24개 표준 시간대로 나누기로 합의했습니다.
실제로 시간대 경계는 깔끔한 경선이 아니라 정치적 국경을 따릅니다. 중국은 지리적으로 5개 시간대에 걸쳐 있지만 단일 공식 시간(UTC+8)을 사용합니다. 인도는 UTC+5:30 — 30분 단위 오프셋을 사용합니다. 네팔은 UTC+5:45를 사용합니다. 실제 시간대 지도는 복잡합니다.
UTC vs. GMT
**GMT(그리니치 표준시)**는 그리니치 왕립 천문대의 평균 태양시입니다. 1세기 이상 세계의 시간 기준이었습니다.
**UTC(협정 세계시)**는 1972년에 GMT를 대체하는 국제 표준으로 도입되었습니다. UTC는 천문 관측이 아닌 원자시계를 기반으로 하여 훨씬 정확합니다. 실용적 목적으로 UTC와 GMT는 같은 시간을 표시하지만, 기술적 기준으로는 UTC가 올바른 것입니다.
왜 "CUT"가 아니라 "UTC"인가요? 이 약어는 영어 "Coordinated Universal Time"(CUT)과 프랑스어 "Temps Universel Coordonné"(TUC)의 타협안입니다. 어느 쪽도 선호하는 약어를 얻지 못해 언어 중립적 대안으로 UTC가 선택되었습니다.
일광 절약 시간: 조직화된 혼돈
약 70개국이 **일광 절약 시간(DST)**을 채택하여, 봄에 시계를 1시간 앞으로, 가을에 1시간 뒤로 조정합니다. 목적은 활동 시간을 일조에 맞추는 것입니다. 그 결과는 반년마다 발생하는 버그의 원천입니다.
주요 복잡성:
- 보편적이지 않음. 아프리카, 아시아, 남미의 대부분은 DST를 채택하지 않습니다. 미국 내에서도 애리조나주와 하와이주는 제외됩니다.
- 날짜가 다름. EU는 3월과 10월 마지막 일요일에 전환합니다. 미국은 3월 두 번째 일요일과 11월 첫 번째 일요일에 전환합니다. 매년 몇 주간 동기화되지 않습니다.
- 모호한 시간. 가을에 시계를 되돌리면, 오전 1시부터 오전 2시까지 1시간이 두 번 발생합니다. 그 날의 "오전 1시 30분" 타임스탬프는 모호합니다.
- 건너뛰는 시간. 봄에 시계를 앞으로 옮기면, 오전 2시부터 오전 3시까지 1시간이 존재하지 않습니다. 그 날 오전 2시 30분에 예약된 회의는 실행되지 않습니다.
- 정치적 변경. 정부는 짧은 통보로 DST 규칙을 변경할 수 있습니다(그리고 실제로 변경합니다). 러시아는 2011년 영구 서머타임을 채택했다가 2014년 영구 표준시로 전환했습니다. 모로코는 DST 규칙을 여러 번 변경했습니다.
ISO 8601: 범용 날짜 형식
모호함을 피하기 위해, 국제 표준 ISO 8601은 명확한 날짜 및 시간 형식을 정의합니다:
2026-03-29T14:30:00Z
2026-03-29T14:30:00+02:00
2026-03-29T14:30:00-05:00
T는 날짜와 시간을 구분합니다.Z는 UTC를 의미합니다(군사 용어로 "Zulu" 시간대).+02:00또는-05:00은 UTC 오프셋입니다.
이 형식은 모호하지 않고, 일반 텍스트로 정렬 가능하며, 날짜 파싱 라이브러리에서 보편적으로 이해됩니다. 의문이 있으면 ISO 8601을 사용하세요.
Unix 타임스탬프
Unix 타임스탬프(에포크 시간 또는 POSIX 시간이라고도 함)는 1970년 1월 1일 00:00:00 UTC — Unix 에포크로 알려진 순간부터 경과한 초 수입니다.
| 사람이 읽을 수 있는 형식 | Unix 타임스탬프 |
|---|---|
| 1970-01-01 00:00:00 UTC | 0 |
| 2000-01-01 00:00:00 UTC | 946684800 |
| 2026-03-29 12:00:00 UTC | 1774987200 |
Unix 타임스탬프에는 시간대가 없습니다 — 항상 UTC입니다. 그래서 소프트웨어에서 시간을 저장하고 비교하는 데 이상적입니다. 로컬 시간대로의 변환은 표시 계층에서만 수행합니다.
2038년 문제: Unix 타임스탬프를 32비트 부호 있는 정수로 저장하는 시스템은 2038년 1월 19일 03:14:07 UTC에 오버플로됩니다. 최대값(2,147,483,647)이 음수로 롤오버되어 1901년 12월로 해석됩니다. 대부분의 현대 시스템은 64비트 정수를 사용하며, 이는 앞으로 2,920억 년 동안 오버플로되지 않습니다.
IANA 시간대 데이터베이스
소프트웨어에는 UTC 오프셋만이 아니라, DST 전환, 정치적 변경, 역사적 예외를 포함한 각 지역의 전체 이력과 미래 규칙이 필요합니다. 이 정보는 IANA 시간대 데이터베이스(Olson 데이터베이스 또는 tzdata라고도 함)에 있습니다.
America/New_York, Europe/Paris, Asia/Tokyo와 같은 식별자를 사용합니다. 각 항목은 해당 위치의 UTC 오프셋과 DST 규칙의 전체 이력을 인코딩합니다.
이것이 시간대를 "+02:00"과 같은 고정 오프셋으로 저장하면 안 되는 이유입니다. 오프셋은 UTC와의 현재 차이를 알려주지만 DST 규칙에 대해서는 아무것도 말해주지 않습니다. Europe/Paris는 겨울에 UTC+1이고 여름에 UTC+2입니다. IANA 식별자는 둘 다를 포착합니다.
소프트웨어의 일반적인 버그
- 시간대 없이 로컬 시간 저장.
2026-03-29 14:30:00과 같은 값은 어떤 시간대를 가리키는지 모르면 의미가 없습니다. 항상 UTC로 저장하거나 오프셋을 포함하세요. - UTC 오프셋을 시간대와 동일시. 3월의 UTC+2가 7월에는 UTC+3일 수 있습니다(해당 지역이 DST를 적용하는 경우). 오프셋이 아닌 IANA 식별자를 저장하세요.
- 스케줄링에서 DST 전환 무시. 오전 2시 30분의 일일 작업은 DST를 처리하지 않으면 연 1회 건너뛰고, 연 1회 두 번 실행됩니다.
- 하루가 24시간이라고 가정. DST 전환일에는 하루가 23시간 또는 25시간입니다. 86,400초를 더해 "내일 같은 시간"을 계산하면 1시간 차이가 납니다.
- JavaScript
Date를 순진하게 사용.new Date("2026-03-29")는 일부 엔진에서 UTC로, 다른 엔진에서 로컬 시간으로 파싱됩니다. 항상 시간대를 명시하세요.
개발자를 위한 모범 사례
- 시간을 UTC로 저장. 사용자의 로컬 시간대로의 변환은 표시 계층에서만 수행.
- IANA 시간대 식별자 사용(
America/New_York). 고정 오프셋(-05:00) 사용하지 않기. - 직렬화에 ISO 8601 사용. 모호하지 않고 보편적으로 파싱 가능.
- 성숙한 날짜 라이브러리 사용. JavaScript에서는
Intl.DateTimeFormat이나date-fns-tz. Python에서는zoneinfo(3.9+) 또는pytz. Java에서는java.time.ZonedDateTime. tzdata를 최신 상태로 유지. 정부는 DST 규칙을 변경합니다. OS와 언어 런타임에 최신 시간대 데이터가 필요합니다.- 여러 시간대에서 테스트. 서버와 사용자가 같은 시간대를 공유한다고 가정하지 마세요.
더 알아보기
시간은 겉보기보다 복잡하지만, 규칙은 잘 문서화되어 있고 도구도 성숙해 있습니다. 핵심은 복잡성을 가정으로 무시하는 것이 아니라 존중하는 것입니다.
- Cron 표현식 해부 — 시간대를 넘나드는 작업 스케줄링
- 해시 생성기와 Regex 테스터 — ToolK의 다른 개발자 도구
