유닉스 타임스탬프를 다룰 때 자주 틀리는 것들
초와 밀리초 혼동, 타임존을 값에 더해 저장하는 실수, 2038년 문제까지. 타임스탬프를 주고받을 때 확인할 것을 정리했습니다.
유닉스 타임스탬프는 1970년 1월 1일 00:00:00 UTC부터 흐른 시간을 초로 센 값입니다. 윤초는 세지 않습니다. 정의가 단순한데도 시스템 사이를 오갈 때 어긋나는 일이 잦습니다.
단위가 섞인다
같은 시각이 단위에 따라 다르게 보입니다.
| 단위 | 자릿수 | 예 |
|---|---|---|
| 초 | 10 | 1785974400 |
| 밀리초 | 13 | 1785974400000 |
| 마이크로초 | 16 | 1785974400000000 |
| 나노초 | 19 | 1785974400000000000 |
밀리초 값을 초로 읽으면 5만 년 뒤가 나오므로 금방 알아차립니다. 반대로 초를 밀리초로 읽으면 1970년 1월 중순쯤이 되어 이것도 눈에 띕니다. 어느 쪽이든 화면에 이상한 날짜가 뜨면 먼저 자릿수를 셉니다.
단위는 환경마다 다릅니다.
- JavaScript
Date.now()— 밀리초 - Python
time.time()— 초(소수점 포함) - Java
System.currentTimeMillis()— 밀리초 - Go
time.Now().Unix()— 초,UnixNano()— 나노초 - PostgreSQL
extract(epoch from ...)— 초(소수점 포함)
경계를 넘을 때마다 변환이 필요합니다. JWT의 exp와 iat는 초 단위인데, 밀리초를 쓰는 언어에서 그대로 비교해 만료 판정이 어긋나는 것이 흔한 예입니다.
타임스탬프에는 타임존이 없다
타임스탬프는 UTC 기준 시각 하나를 가리키는 숫자입니다. 타임존은 그 숫자를 사람이 읽는 문자열로 바꿀 때 붙는 것입니다.
그래서 저장된 값에 9시간(32400초)을 더해 두는 처리는 잘못입니다. 한국 시각으로 보이게 하려고 그렇게 해 두면, 그 값은 더 이상 유닉스 타임스탬프가 아니고 다른 시스템이 읽을 때마다 9시간씩 어긋납니다.
원칙은 둘입니다.
- 저장은 UTC로. 타임스탬프 그대로 저장합니다
- 변환은 표시할 때. 사용자의 타임존을 적용해 문자열을 만듭니다
로그에 시각을 남길 때도 마찬가지입니다. 서버마다 로컬 시각으로 적어 두면 여러 서버의 로그를 시간순으로 합칠 수 없습니다.
미래의 약속은 타임스탬프로 저장하지 않는다
이미 일어난 일은 타임스탬프로 저장하는 것이 맞습니다. 그 시점은 다시 바뀌지 않습니다.
미래 일정은 다릅니다. "2027년 3월 15일 오전 9시, 서울"을 타임스탬프로 바꿔 저장하면, 그 사이에 해당 지역의 시간 규칙이 바뀔 경우 약속한 시각과 어긋납니다. 서머타임 시행일이 바뀌거나 표준시 자체가 조정되는 일은 실제로 일어납니다.
미래 일정은 로컬 시각과 타임존 식별자를 나눠 저장하고, 알림을 보낼 때 계산합니다.
2027-03-15T09:00:00 + Asia/Seoul
타임존은 Asia/Seoul 같은 IANA 식별자로 저장합니다. KST나 +09:00으로 저장하면 서머타임이 있는 지역에서 어느 쪽인지 알 수 없습니다.
2038년
32비트 부호 있는 정수는 2038년 1월 19일 03:14:07 UTC에 넘칩니다. 그 다음 초에 음수가 되어 1901년으로 돌아갑니다.
64비트로 저장하면 문제가 없고, 요즘 언어와 데이터베이스는 대부분 그렇게 합니다. 남아 있는 위험은 오래된 임베디드 시스템, 32비트로 고정된 파일 형식, 그리고 int를 명시적으로 쓴 오래된 코드 쪽입니다.
만료일을 멀리 잡는 기능에서는 이미 드러나기도 합니다. 20년짜리 기간을 계산하는 코드는 지금 시점에서 이미 경계를 넘습니다.
확인할 목록
- 받은 값의 자릿수를 세어 단위를 확인합니다
- 저장은 UTC, 표시할 때 변환합니다
- 미래 일정은 로컬 시각 + IANA 타임존으로 저장합니다
- 날짜 경계가 걸린 로직은 UTC와 로컬 타임존 양쪽에서 확인합니다.
2026-08-06 09:00 KST는 UTC로는 전날입니다
tools.onuel.dev에서 타임스탬프 변환으로 값을 원하는 타임존의 날짜로 바꿔 볼 수 있습니다. 현재 값과 여러 개를 한 번에 바꾸는 것, 타임존 사이 변환도 있습니다.
- #타임스탬프
- #날짜
- #타임존