유닉스 타임스탬프 자릿수로 단위 구분하는 법

API 응답이나 서버 로그에 찍힌 1784298258 같은 숫자가 정확히 어떤 시각을 가리키는지는 자릿수만 세어도 판별할 수 있습니다. 유닉스 타임스탬프는 초 단위인지 밀리초 단위인지에 따라 자릿수 범위가 정해져 있습니다.
이 규칙을 모르고 숫자를 그대로 자바스크립트 Date 생성자에 넣으면 1970년대 근처 날짜나 서기 수만 년대 같은 터무니없는 날짜가 나옵니다. 이 글은 자릿수만으로 초·밀리초·마이크로초·나노초를 구분하는 계산 규칙을 정리합니다.
요약 ① 자릿수 1
11자리는 초, 1214자리는 밀리초, 15~17자리는 마이크로초, 18자리 이상은 나노초입니다. ② 10자리 초 값을 밀리초로 착각해 그대로 Date에 넣으면 1970년 근처가 되고, 13자리 밀리초 값을 초로 착각해 1000을 곱하면 서기 수만 년 같은 값이 나옵니다. ③ 같은 타임스탬프도 UTC와 로컬 시각은 시간대 오프셋만큼 다르게 보이고, 음수 값은 1970년 이전 시점을 의미합니다.
자릿수를 착각하는 일이 실무에서 실제로 일어나는 이유
서버 로그나 API 응답에는 타임스탬프가 단위 표시 없이 숫자만 찍혀 나오는 경우가 많습니다. 시스템마다 초 단위로 내려주기도 하고 밀리초 단위로 내려주기도 해서, 필드 이름이 같아도(created_at, timestamp 등) 실제 값의 자릿수는 다를 수 있습니다.
문제는 자바스크립트의 Date 생성자가 항상 밀리초를 기준으로 동작한다는 점입니다. new Date(x)는 x를 1970년 1월 1일 0시(UTC)로부터 몇 밀리초가 지났는지로 해석합니다.
여기에 초 단위 숫자를 그대로 넣으면 실제보다 1000분의 1로 작은 값을 밀리초로 읽은 셈이 되어, 계산된 날짜가 1970년 근처로 튑니다.
반대 방향의 실수도 있습니다. 밀리초 단위 숫자를 초 단위라고 착각해 1000을 곱한 뒤 Date에 넣으면, 실제 날짜보다 1000배 먼 미래로 튀어 버립니다. 두 실수 모두 코드가 에러 없이 그대로 실행되기 때문에, 화면에 이상한 날짜가 찍히기 전까지는 눈치채기 어렵습니다.
도구 없이 자릿수만 세어서 직접 판별하는 방법
판별 규칙과 11자리가 경계인 이유
판별 규칙은 이렇습니다. 정수 부분의 자릿수를 세어 111자리면 초, 1214자리면 밀리초, 15~17자리면 마이크로초, 18자리 이상이면 나노초로 봅니다.
경계선이 11자리인 데는 이유가 있습니다. 11자리 숫자의 최댓값인 99999999999를 초 단위로 변환하면 5138년 11월 16일입니다.
즉 초 단위 타임스탬프는 11자리만으로도 서기 5138년까지 표현이 가능하므로, 12자리 이상의 숫자가 나왔다면 초가 아니라 더 작은 단위일 가능성이 훨씬 큽니다.
실제 숫자로 검증하기
실제 숫자로 검증해보겠습니다. 이 글을 쓰는 시점의 초 단위 타임스탬프는 1784298258(10자리)이고, 초로 정확히 해석하면 2026년 7월 17일 14시 24분(UTC)입니다.
그런데 이 숫자를 실수로 new Date(1784298258)처럼 밀리초 자리에 그대로 넣으면 결과는 1970년 1월 21일이 나옵니다. 1784298258밀리초는 약 20일에 불과하기 때문입니다.
같은 순간의 밀리초 단위 값은 1784298258087(13자리)입니다. 이 숫자를 반대로 초 단위라고 착각해 1000을 곱해 new Date(1784298258087 * 1000)처럼 넣으면 결과는 서기 58512년이라는 있을 수 없는 날짜가 나옵니다.
계산 순서로 정리하기
계산 순서는 다음과 같습니다.
- 숫자의 자릿수를 센다.
- 자릿수 규칙(11 / 14 / 17 자리 경계)에 따라 단위를 정한다.
- 밀리초라면 1000으로 나눠 초로 바꾸거나, 초를 자바스크립트 Date에 넣으려면 반대로 1000을 곱해 밀리초로 바꾼다.
- 만든 Date 객체를 toISOString()(UTC), toString()(로컬)로 각각 확인한다.
자릿수를 세고 나눗셈·곱셈을 손으로 반복하는 대신, 저희 도구로 확인하기.
숫자의 자릿수를 자동 감지해 초·밀리초·마이크로초·나노초와 UTC·로컬 시각을 즉시 계산합니다. 무료이며 브라우저에서만 처리됩니다.

자주 헷갈리는 지점들
같은 순간을 가리키는 값이라도 단위별로 자릿수가 다르게 나타납니다. 아래는 방금 검증한 숫자를 그대로 정리한 표입니다.
| 자릿수 | 단위 | 예시 값 | 가리키는 시각(UTC) |
|---|---|---|---|
| 1~11자리 | 초 | 1784298258 | 2026-07-17 14:24:18 |
| 12~14자리 | 밀리초 | 1784298258087 | 2026-07-17 14:24:18.087 |
| 15~17자리 | 마이크로초 | 1784298258087000 | 2026-07-17 14:24:18.087 (같은 순간) |
| 18자리 이상 | 나노초 | 1784298258087000000 | 2026-07-17 14:24:18.087 (같은 순간) |
UTC·로컬 시각과 상대 시간의 차이
UTC와 로컬 시각이 다르게 보이는 이유는 타임스탬프 자체가 특정 시간대에 속하지 않는 절대적인 값(1970년 1월 1일 0시 UTC로부터 지난 시간)이기 때문입니다. 로컬 시각은 이 절대값에 브라우저가 설정한 시간대 오프셋을 더한 결과입니다.
예를 들어 위 표의 값은 UTC로 7월 17일 14시 24분이지만, 한국 표준시(UTC+9)를 기준으로 하면 같은 순간이 7월 17일 23시 24분으로 표시됩니다.
상대 시간("3시간 후" 같은 표시)은 대상 시각과 현재 시각의 차이를 초 단위로 계산한 뒤, 분·시간·일 중 사람이 읽기 쉬운 단위로 환산해 표시한 값입니다. 대상이 현재보다 미래면 "~후", 과거면 "~전"으로 붙습니다.
음수 타임스탬프와 계산된 하위 단위
음수 타임스탬프도 유효한 값입니다. 음수는 1970년 1월 1일 0시(UTC) 이전 시점을 의미합니다. 예를 들어 -3600은 그 기준 시각으로부터 3600초(1시간) 전인 1969년 12월 31일 23시(UTC)를 가리킵니다.
마지막으로, 마이크로초·나노초 값은 밀리초 값에 1000, 1,000,000을 각각 곱해서 만든 계산값이라는 점도 알아둘 필요가 있습니다. 원본 시스템이 실제로 마이크로초 단위까지 독립적으로 측정했다면, 그 원본 값의 하위 자릿수는 이 계산값과 다를 수 있습니다.
정리
- 자릿수 1
11자리는 초, 1214자리는 밀리초, 15~17자리는 마이크로초, 18자리 이상은 나노초입니다. - 11자리 초 값의 최댓값도 서기 5138년에 불과해, 12자리 이상이면 초가 아닐 가능성이 큽니다.
- 10자리 초 값을 밀리초 자리에 그대로 넣으면 1970년대 근처, 13자리 밀리초 값을 초로 착각해 1000을 곱하면 터무니없는 미래가 나옵니다.
- 같은 타임스탬프라도 UTC와 로컬 시각은 시간대 오프셋만큼 다르게 표시되며, 음수 값은 1970년 이전 시점을 의미합니다.
- 마이크로초·나노초 값은 밀리초 값을 곱해 만든 계산값입니다.
숫자의 자릿수를 자동 감지해 초·밀리초·마이크로초·나노초와 UTC·로컬 시각을 즉시 계산합니다. 무료이며 브라우저에서만 처리됩니다.
자주 묻는 질문
자릿수 규칙만으로 단위를 항상 확신할 수 있나요?
현재와 가까운 연도대를 다루는 실무 타임스탬프라면 이 규칙으로 충분히 구분됩니다. 다만 이는 "초 단위 값은 서기 5138년까지 11자리로 표현된다"는 계산에 기반한 관례적 판별법이며, 그보다 훨씬 먼 미래를 가리키는 초 단위 값이라면 12자리 이상이 될 수 있어 규칙이 어긋날 수 있습니다.
음수 타임스탬프도 입력할 수 있나요?
네, 1970년 1월 1일 이전 날짜를 나타내는 음수 값도 정상적으로 계산됩니다. 예를 들어 -3600은 1969년 12월 31일 23시(UTC)를 의미합니다.
입력한 숫자가 서버로 전송되나요?
아니요. 모든 단위 판별과 날짜 계산은 브라우저 안에서 자바스크립트로 즉시 처리되며, 입력한 숫자는 서버로 전송되지 않습니다.
마이크로초·나노초 값도 실측된 만큼 정밀한가요?
아닙니다. 표시되는 마이크로초·나노초 값은 밀리초 값에 1000, 1,000,000을 곱해서 만든 계산값입니다. 원본 시스템이 실제로 마이크로초 단위까지 독립적으로 측정한 값이라면, 그 값의 하위 자릿수와는 다를 수 있습니다.
