Unix 타임스탬프 단위 혼동: 초(seconds) vs 밀리초(milliseconds) 오류
Unix 타임스탬프는 시간을 숫자로 표현하는 보편적인 방식입니다. 하지만 이 숫자가 초(seconds) 단위인지 밀리초(milliseconds) 단위인지를 혼동하여 치명적인 시간 오류나 만료 시간 불일치 버그를 유발하는 경우가 매우 흔합니다.
1) 초 단위 타임스탬프 (10자리 숫자)
전통적인 Unix 타임스탬프는 1970년 1월 1일 00:00:00 UTC 기준으로 경과한 **초(seconds)**를 나타냅니다. 대부분의 시스템이나 API에서 long 또는 int 타입으로 사용되며, 일반적으로 10자리 숫자 형태를 띱니다.
- 예시:
1678886400(2023년 3월 15일 00:00:00 UTC) - 주요 사용처: Unix/Linux 시스템, 일부 HTTP 헤더 (
Expires,Date), 오래된 API
2) 밀리초 단위 타임스탬프 (13자리 숫자)
자바스크립트의 Date.now()나 자바의 System.currentTimeMillis()처럼 최신 언어 및 시스템에서는 정확도를 높이기 위해 밀리초(milliseconds) 단위를 주로 사용합니다. 이는 초 단위 타임스탬프에 000을 붙인 형태, 즉 13자리 숫자 형태를 띱니다.
- 예시:
1678886400000(2023년 3월 15일 00:00:00 UTC) - 주요 사용처: JavaScript, Java, 최신 REST API, JWT 클레임 (
exp,iat등)
3) 단위 혼동으로 발생하는 문제
- 만료 시간 오류: JWT
exp클레임이 밀리초인데 초 단위로 해석하여 토큰이 실제보다 1000배 빠르게 만료되거나, 반대로 만료되지 않는 문제 - 데이터 불일치: 서로 다른 시스템 간에 시간 데이터를 주고받을 때 단위가 달라 잘못된 비교나 정렬 결과
- 로깅/모니터링: 로그나 메트릭에서 시간 값이 예상과 다르게 표시되어 디버깅에 혼란
4) 단위 혼동 해결 방법
가장 중요한 것은 **"입력받은 타임스탬프의 자릿수를 확인"**하는 것입니다.
- 10자리 숫자: 초 단위로 간주하고, 밀리초가 필요하면
* 1000을 합니다. - 13자리 숫자: 밀리초 단위로 간주하고, 초가 필요하면
/ 1000을 합니다.
const timestamp = 1678886400; // 10자리 (초)
const dateFromSeconds = new Date(timestamp * 1000);
console.log(dateFromSeconds); // Wed Mar 15 2023 ...
const msTimestamp = 1678886400000; // 13자리 (밀리초)
const dateFromMilliseconds = new Date(msTimestamp);
console.log(dateFromMilliseconds); // Wed Mar 15 2023 ...
// JWT 검증 라이브러리에서는 보통 밀리초를 기대하므로 주의
5) 체크리스트
- 외부 시스템이나 API에서 받은 타임스탬프의 자릿수를 확인했는가?
-
new Date()나Date.parse()에 넣기 전, JavaScript가 기대하는 밀리초 단위로 변환했는가? - JWT
exp,iat클레임을 처리할 때 단위 오류가 없는지 확인했는가?
타임스탬프 단위를 쉽게 변환하고 확인하고 싶다면 Timestamp Converter 도구를 사용해 보세요.