서버 로그를 열었더니 시간이 1709251200으로 찍혀 있다. 언뜻 보면 전화번호 같지만, 이건 날짜다. 1970년 1월 1일 자정(UTC)부터 지금까지 흐른 초(秒)의 수, 즉 Unix 타임스탬프다.
Unix 타임스탬프의 구조
1970년 1월 1일 00:00:00 UTC를 기준점(Epoch)으로 삼고, 그 이후 경과한 초를 정수로 표현한다.
| 타임스탬프 | 날짜 (UTC) | 날짜 (한국시간) |
|---|---|---|
| 0 | 1970-01-01 00:00:00 | 1970-01-01 09:00:00 |
| 1000000000 | 2001-09-09 01:46:40 | 2001-09-09 10:46:40 |
| 1709251200 | 2024-03-01 00:00:00 | 2024-03-01 09:00:00 |
| 1767225600 | 2025-12-31 00:00:00 | 2026-01-01 09:00:00 |
한국은 UTC+9이므로 타임스탬프를 한국 시간으로 변환하면 9시간이 더해진다. 이 시차 때문에 실수가 빈번하게 발생한다.
초(s) vs 밀리초(ms) 구분하기
같은 시점을 표현하는 두 가지 형태가 혼재한다.
- 초 단위 (10자리)
- 1709251200 — Unix/Linux 시스템, PHP, Python의 time.time()에서 주로 사용
- 밀리초 단위 (13자리)
- 1709251200000 — JavaScript의 Date.now(), Java의 System.currentTimeMillis()에서 사용
API에서 받은 타임스탬프가 10자리인지 13자리인지에 따라 1000을 곱하거나 나눠야 한다. 이걸 놓치면 1970년대 날짜가 나오거나, 수천 년 뒤 날짜가 나오는 버그가 생긴다.
타임스탬프를 날짜로 바꾸는 법
코드에서
// JavaScript
new Date(1709251200 * 1000).toISOString()
// "2024-03-01T00:00:00.000Z"
# Python
from datetime import datetime
datetime.utcfromtimestamp(1709251200)
# 2024-03-01 00:00:00
빠르게 확인하고 싶을 때
로그에 찍힌 타임스탬프를 코드 한 줄 없이 바로 확인하려면 타임스탬프 변환기에 숫자를 붙여넣으면 된다. 초 단위와 밀리초 단위를 자동 감지하고, 로컬 시간, UTC, ISO 8601 형식으로 동시에 보여준다. 반대로 날짜를 선택해서 타임스탬프로 바꾸는 것도 가능하다.
개발 실무에서 흔한 시간 관련 실수
- 시간대 미적용: UTC 타임스탬프를 그대로 화면에 표시하면 한국 사용자에게 9시간 빠른 시간이 보인다. 프론트엔드에서 로컬 시간대로 변환해야 한다.
- 초/밀리초 혼동: JavaScript에서 받은 13자리 값을 Python에서 그대로 쓰면 53000년쯤 되는 날짜가 나온다. 1000으로 나눠야 한다.
- 서머타임: 해외 서비스라면 서머타임(DST) 적용 여부를 고려해야 한다. 한국은 서머타임이 없지만, 미국/유럽 사용자 대상이라면 주의가 필요하다.
- 2038년 문제: 32비트 시스템에서 Unix 타임스탬프는 2038년 1월 19일에 오버플로우된다. 현재 대부분의 시스템은 64비트로 전환되었지만, 레거시 시스템이 남아 있다면 점검이 필요하다.
TIP DB에 시간을 저장할 때는 항상 UTC 기준 타임스탬프로 저장하고, 화면에 표시할 때 사용자의 로컬 시간대로 변환하는 게 가장 안전한 패턴이다.
1709251200이라는 숫자가 2024년 3월 1일이라는 걸 머릿속으로 계산할 수는 없다. 도구에 넣으면 1초 만에 나오니, 로그 분석이나 디버깅할 때 시간을 아낄 수 있다.