타임스탬프 날짜 변환, 초·밀리초와 UTC 읽기

API 응답이나 데이터베이스에 1700000000 같은 숫자로 저장된 시각을 사람이 읽는 날짜로 바꾸려는 분을 위한 글입니다. 유닉스 타임스탬프는 1970년 1월 1일 0시(UTC)부터 흐른 초 또는 밀리초일 뿐이라, 규칙만 알면 어떤 숫자가 몇 시인지 정확히 읽어낼 수 있습니다. 반대로 단위를 착각하면 같은 숫자가 1970년으로도, 수천 년 뒤로도 보입니다.
요약 ① 타임스탬프는 1970-01-01 00:00:00 UTC(에포크)부터 흐른 초 또는 밀리초입니다. ② 자릿수가 11자리 이하면 초, 12자리 이상이면 밀리초로 판별하며, 단위를 착각하면 결과 날짜가 약 1000배 어긋납니다. ③ 같은 타임스탬프라도 현지·UTC·ISO 세 형식은 시간대 오프셋만큼 다르게 표시됩니다.
로그에는 단위 표시 없이 숫자만 찍혀 있습니다
서버 로그나 API 응답에는 시각이 created_at: 1700000000처럼 숫자 하나로만 남는 경우가 많습니다. 사람이 읽는 "2023년 11월"이 아니라, 에포크로부터의 경과 시간을 그대로 저장하기 때문입니다.
문제는 이 숫자에 "초"인지 "밀리초"인지 단위가 함께 적혀 있지 않다는 점입니다. 어떤 시스템은 초 단위로, 어떤 시스템은 밀리초 단위로 기록해서, 필드 이름이 같아도 실제 값의 자릿수는 다를 수 있습니다.
그래서 로그에서 1700000000과 1700000000000을 나란히 보면, 둘이 같은 순간인지 전혀 다른 시각인지 한눈에 알기 어렵습니다. 이 글은 그 숫자를 정확한 날짜로 읽는 규칙을 정리합니다.
도구 없이 직접 변환하는 방법
1단계 — 에포크 정의부터
유닉스 타임스탬프의 기준점(에포크)은 1970년 1월 1일 00:00:00 UTC입니다. 타임스탬프는 이 순간부터 몇 초(또는 몇 밀리초)가 지났는지를 나타내는 하나의 숫자입니다.
여기서 중요한 건 기준이 UTC라는 점입니다. 타임스탬프 자체에는 시간대 정보가 없고, 어느 지역에서 읽든 같은 절대적인 순간을 가리킵니다.
2단계 — 자릿수로 단위 판별
정수 부분의 자릿수를 셉니다. 11자리 이하면 초, 12자리 이상이면 밀리초로 봅니다. 현재 시점의 초 단위 값은 10자리, 밀리초 단위 값은 13자리라 실무에서는 대개 명확히 갈립니다.
초 단위 값을 날짜로 바꾸려면 밀리초로 맞춰야 합니다. 자바스크립트의 Date는 항상 밀리초를 기준으로 동작하기 때문에, 초 값에는 1000을 곱해야 합니다.
3단계 — 실제로 계산하기
가장 확실한 방법은 브라우저 개발자 콘솔입니다. 초 값이라면 1000을 곱해 넣습니다.
new Date(1700000000 * 1000).toString() // 현지 시각
new Date(1700000000 * 1000).toUTCString() // UTC
new Date(1700000000 * 1000).toISOString() // ISO 8601
명령줄이 편하다면 맥에서는 date -r 1700000000 -u, 리눅스에서는 date -d @1700000000 -u로 UTC 시각을 볼 수 있습니다.
스프레드시트에서는 =A1/86400 + DATE(1970,1,1) 수식이 초 값을 UTC 날짜로 바꿔 줍니다. 한국 시각으로 보려면 여기에 9/24를 더하면 됩니다(UTC+9).
4단계 — UTC를 현지 시각으로
UTC 값이 나왔다면 자기 지역의 오프셋을 더합니다. 한국 표준시(KST)는 UTC+9이므로, UTC에 9시간을 더한 값이 현지 시각입니다.
저희 도구로 확인하기.
숫자를 넣으면 초·밀리초를 자동 판별해 현지·UTC·ISO 시각으로, 날짜를 고르면 초·밀리초 값으로 바꿔 줍니다. 설치 없이 브라우저에서 처리됩니다.

같은 값이 현지·UTC·ISO로 다르게 보이는 이유
도구에 1700000000을 넣으면 세 줄이 나옵니다. 같은 숫자 하나인데 시각이 서로 다르게 보여 혼란스러울 수 있습니다.
| 형식 | 표시 | 의미 |
|---|---|---|
| 현지(로컬) | 2023-11-15 07:13:20 | 브라우저 시간대(KST=UTC+9) 기준 |
| UTC | 2023-11-14 22:13:20 UTC | 시간대 오프셋 0 기준 |
| ISO 8601 | 2023-11-14T22:13:20.000Z | UTC를 국제 표준 문자열로 표기 |
세 값은 모두 같은 순간을 가리킵니다. 타임스탬프는 시간대가 없는 절대값이라, 어느 형식으로 읽느냐에 따라 표시만 달라질 뿐입니다.
현지 시각이 UTC보다 9시간 앞선 이유는 KST가 UTC+9이기 때문입니다. 이 예에서는 9시간을 더하다 보니 날짜까지 11월 14일에서 15일로 하루 넘어갔습니다.
ISO 8601 문자열 끝의 Z는 "이 시각이 UTC"라는 표시입니다. 그래서 ISO와 UTC 줄은 형식만 다르고 가리키는 시각은 같습니다.
자주 하는 실수: 단위를 착각하면 1000배 어긋납니다
가장 흔한 실수는 단위를 잘못 잡는 것입니다. 초 값을 밀리초로, 또는 밀리초 값을 초로 착각하면 결과가 약 1000배 어긋납니다.
| 입력한 숫자 | 취급 단위 | 계산되는 시각(UTC) |
|---|---|---|
| 1700000000 (10자리) | 초 (정상) | 2023-11-14 22:13:20 |
| 1700000000000 (13자리) | 밀리초 (정상) | 2023-11-14 22:13:20 |
| 1700000000 | 밀리초로 착각 | 1970-01-20 16:13:20 |
1700000000은 원래 초 값이라 1000을 곱해야 2023년이 됩니다. 이걸 그대로 밀리초로 넣으면 약 17억 밀리초, 즉 20일 남짓밖에 안 되므로 1970년 1월로 튑니다.
반대로 13자리 밀리초 값에 실수로 1000을 한 번 더 곱하면 서기 수만 년대의 있을 수 없는 날짜가 나옵니다. 도구는 자릿수로 단위를 먼저 판별해 이 곱셈 실수를 줄여 줍니다.
다만 자릿수 판별은 관례라는 점도 알아두면 좋습니다. 12자리 이상을 밀리초로 보기 때문에, 아주 먼 미래를 가리키는 초 값이라면 규칙이 어긋날 수 있습니다.
정리
- 유닉스 타임스탬프는 1970-01-01 00:00:00 UTC(에포크)부터 흐른 초 또는 밀리초입니다.
- 자릿수가 11자리 이하면 초, 12자리 이상이면 밀리초입니다. 현재 초 값은 10자리, 밀리초 값은 13자리입니다.
- 단위를 착각하면 결과가 약 1000배 어긋나, 1970년 근처나 터무니없는 미래로 튑니다.
- 같은 타임스탬프라도 현지·UTC·ISO는 시간대 오프셋만큼 다르게 표시될 뿐, 같은 순간입니다.
- ISO 8601 끝의
Z는 그 시각이 UTC라는 표시입니다.
숫자를 넣으면 초·밀리초를 자동 판별해 현지·UTC·ISO 시각으로, 날짜를 고르면 초·밀리초 값으로 바꿔 줍니다. 설치 없이 브라우저에서 처리됩니다.
자주 묻는 질문
10자리와 13자리 숫자는 어떻게 구분하나요?
자릿수로 판별합니다. 도구는 11자리 이하를 초, 12자리 이상을 밀리초로 봅니다. 현재 시점 기준으로 초 단위 값은 10자리, 밀리초 단위 값은 13자리라 대개 명확히 갈립니다. 초 값은 날짜로 바꾸기 위해 내부적으로 1000을 곱해 계산합니다.
현지 시각과 UTC가 왜 다르게 나오나요?
타임스탬프는 시간대가 없는 절대값이고, 현지 시각은 여기에 브라우저 시간대 오프셋을 더한 결과이기 때문입니다. 한국 표준시는 UTC+9이라 현지 시각이 UTC보다 9시간 앞서 보이며, 경우에 따라 날짜도 하루 넘어갑니다. 두 줄은 표시만 다를 뿐 같은 순간을 가리킵니다.
날짜를 반대로 타임스탬프로 바꿀 수도 있나요?
네. 도구의 두 번째 칸에서 날짜와 시각을 고르면 그 순간의 초 값과 밀리초 값을 함께 보여 주고, 각각 복사할 수 있습니다. 초 값은 밀리초를 1000으로 나눈 뒤 소수점을 버린 정수입니다.
입력한 숫자가 서버로 전송되나요?
아니요. 단위 판별과 날짜 계산은 모두 브라우저 안에서 즉시 처리됩니다. 별도의 전송이나 설치 과정 없이, 입력하는 즉시 결과가 바뀝니다.
