서버 로그를 열었는데 시간 필드에 1709251200이라고만 찍혀 있다. 날짜도 시간도 아닌 그냥 숫자 10자리. 이걸 사람이 읽을 수 있는 날짜로 바꾸려면 Unix 타임스탬프가 뭔지부터 알아야 한다.
Unix 타임스탬프의 정체
Unix 타임스탬프(Epoch time)는 1970년 1월 1일 00:00:00 UTC부터 지금까지 흘러간 초(秒)의 수다. 컴퓨터가 날짜를 다루는 가장 원시적인 방식이고, 시간대나 형식에 영향을 받지 않기 때문에 서버 간 통신에서 표준처럼 쓰인다.
예시 1709251200 → 2024년 3월 1일 09:00:00 (KST)
0 → 1970년 1월 1일 00:00:00 (UTC)
밀리초 단위도 있다. JavaScript의 Date.now()는 13자리 숫자를 반환하는데, 이건 초가 아니라 밀리초 타임스탬프다. 10자리면 초, 13자리면 밀리초로 구분하면 된다.
개발할 때 타임스탬프를 만나는 상황
- 서버 로그 분석
- Nginx, Apache 액세스 로그에 요청 시각이 타임스탬프로 기록된다. 장애 발생 시점을 추적하려면 변환이 필수다.
- API 응답 파싱
- 외부 API가 created_at 필드를 타임스탬프로 내려주는 경우가 많다. 특히 트위터, 텔레그램 등 해외 서비스는 초 단위 타임스탬프를 기본으로 쓴다.
- DB 쿼리 디버깅
- MySQL의 UNIX_TIMESTAMP() 함수로 저장된 값을 직접 확인해야 할 때, 숫자만 봐서는 감이 안 온다.
- JWT 토큰 확인
- JWT의 exp(만료 시간), iat(발급 시간) 클레임이 타임스탬프 형식이다. 토큰이 만료됐는지 확인하려면 현재 타임스탬프와 비교해야 한다.
초 vs 밀리초, 헷갈릴 때
| 구분 | 자릿수 | 사용처 |
|---|---|---|
| 초(seconds) | 10자리 | Python time.time(), PHP time(), Unix 시스템 |
| 밀리초(milliseconds) | 13자리 | JavaScript Date.now(), Java System.currentTimeMillis() |
API 문서에 "timestamp"라고만 적혀 있으면 초인지 밀리초인지 확인부터 해야 한다. 잘못 넣으면 1970년이나 수만 년 뒤 날짜가 나온다.
변환하는 방법
코드 한 줄로도 되지만, 로그 수십 줄을 하나씩 변환하기엔 번거롭다. 타임스탬프 변환기에 숫자를 넣으면 로컬 시간, UTC, ISO 8601 세 가지 형식으로 결과가 나온다. 반대로 날짜를 입력해서 타임스탬프 값을 뽑는 것도 가능하다. 페이지 상단에는 현재 타임스탬프가 1초마다 갱신되니까, 테스트 데이터에 "지금" 시각을 넣어야 할 때 바로 복사해서 쓸 수 있다.
2038년 문제
32비트 시스템에서 타임스탬프를 signed int로 저장하면, 2038년 1월 19일 03:14:07 UTC에 오버플로가 발생한다. 이후 시각은 음수가 되어 1901년으로 돌아간다. Y2K와 비슷한 문제인데, 대부분의 최신 시스템은 64비트로 전환되어 걱정할 필요가 없다. 다만 오래된 임베디드 장비나 레거시 코드에서는 여전히 주의가 필요하다.
타임스탬프는 눈에 안 읽히는 대신, 시간대 변환 없이 전 세계 어디서든 같은 값을 공유할 수 있다는 게 장점이다. 변환할 일이 자주 있다면 브라우저 북마크에 하나 걸어두는 것만으로도 시간이 절약된다.