타임스탬프 날짜가 이상할 때: 초와 밀리초 구분하기
서버 로그나 외부 연동 데이터에서 1767225600과 같은 숫자를 받아 날짜로 바꿨을 때 1970년 1월이나 수만 년 뒤의 날짜가 표시되는 상황을 자주 마주합니다. 이러한 문제는 데이터 자체가 완전히 망가진 것이 아니라, 시간 단위를 초(Seconds)로 다루는지 밀리초(Milliseconds)로 다루는지 맞지 않거나 기준 시간대(Timezone) 처리가 누락되어 발생합니다.
1. 연도가 비정상적으로 계산되는 원인
POSIX 타임스탬프는 1970년 1월 1일 00:00:00 UTC를 기점(Epoch)으로 경과한 시간을 표현합니다. 날짜 파싱 라이브러리나 내장 함수는 기본 입력 단위를 특정 기준(대부분 초 또는 밀리초)으로 가정합니다.
- 밀리초를 초 단위 함수에 넘긴 경우: 13자리 숫자인
1767225600000을 초 단위 입력으로 해석하면 기점으로부터 약 5만 6천 년 뒤의 미래 시점으로 계산되거나 지원 범위를 벗어나 넘침(Overflow) 오류가 발생합니다. - 초를 밀리초 단위 함수에 넘긴 경우: 10자리 숫자인
1767225600을 밀리초 입력으로 해석하면 겨우 20여 일 지난 시점으로 축소되어 1970년 1월 언저리의 날짜가 출력됩니다.
이전에 정리했던 JSON 오류 찾기: 쉼표·따옴표·긴 숫자 확인 문서에서 다룬 정수형 처리처럼, 숫자 데이터는 파싱하기 전 명세서와 단위를 함께 점검해야 오차를 막을 수 있습니다.
2. 초와 밀리초, 그리고 시간대 기준 데이터 확인
동일한 특정 시점을 나타낼 때 초 단위 값과 밀리초 단위 값, 그리고 협정 세계시(UTC)와 한국 표준시(KST, UTC+09:00)의 표현 방식은 아래와 같이 달라집니다.
{
"seconds": 1767225600,
"milliseconds": 1767225600000,
"UTC": "2026-01-01T00:00:00+00:00",
"Korea": "2026-01-01T09:00:00+09:00"
}초 단위(10자리) 1767225600에 1,000을 곱하면 밀리초 단위(13자리) 1767225600000이 됩니다. 또한 동일한 타임스탬프 값이라도 UTC 기준으로 읽으면 2026-01-01T00:00:00+00:00이지만, 한국 시간대(+09:00)로 변환하면 9시간이 더해진 2026-01-01T09:00:00+09:00이 됩니다.
3. 타임스탬프 변환 점검 순서
숫자형 날짜를 변환할 때는 단순 자릿수만으로 판단하지 않고 아래 순서로 단위를 검증한 뒤 변환해야 합니다.
- 연동 규격 및 API 명세 확인: 제공 시스템이 타임스탬프를 초 단위(UNIX epoch seconds)로 반환하는지 밀리초(epoch milliseconds)로 반환하는지 명세를 우선 확인합니다.
- 입력 값의 자릿수 및 단위 조정: 사용하는 언어나 환경의 함수 요구사항에 맞게 변환합니다. 예컨대 초 단위를 요구하는 함수에 13자리 밀리초가 들어온다면
1000으로 나누어 초 단위 실수나 정수로 맞춥니다. - 시간대 명시(Aware datetime 변환): 시간대를 지정하지 않는 Naive 변환 대신, Python datetime.fromtimestamp 공식 문서에 나온 것처럼
tz매개변수에 명시적인 시간대(예: UTC)를 넘겨 인식 가능한 객체로 변환합니다. - 표시할 로컬 시간대로 최종 변환: 저장과 처리는 일관된 기준(UTC)으로 진행하고, 최종 사용자 화면에 출력할 때만 목표 지역 시간대(한국 시간 등)를 적용합니다.
4. 변환 코드 예시와 주의할 점
Python의 datetime 모듈을 사용하는 경우 단위와 시간대 지정에 유의해야 합니다.
from datetime import datetime, timezone, timedelta
sec_val = 1767225600
ms_val = 1767225600000
# 1. 밀리초 값을 초 단위 함수에 넣을 때는 1000을 나눔
utc_dt = datetime.fromtimestamp(ms_val / 1000, tz=timezone.utc)
# 2. 한국 표준시(+09:00) 변환
kst = timezone(timedelta(hours=9))
kst_dt = utc_dt.astimezone(kst)Python 공식 문서에 따르면 fromtimestamp() 함수에 tz 인수를 넘기지 않으면 운영체제 로컬 시간대로 해석된 Naive 객체가 생성되어 의도치 않은 시간 왜곡이 생길 수 있습니다. 또한 시스템 C 라이브러리의 구현 범위에 따라 지원 범위를 벗어난 타임스탬프는 OverflowError나 OSError를 일으킬 수 있습니다.
| 구분 | 초 (Seconds) | 밀리초 (Milliseconds) |
|---|---|---|
| 예시 값 | 1767225600 | 1767225600000 |
| 자릿수 (2020~2030년대 기준) | 10자리 | 13자리 |
| 초 단위 함수에 그대로 입력 시 | 정상 날짜 변환 | OverflowError 또는 먼 미래 연도 |
| 밀리초 단위 함수에 그대로 입력 시 | 1970년 1월 부근 날짜 | 정상 날짜 변환 |
5. 이 방법으로 확인할 수 없는 한계
자릿수와 나눗셈(1,000)을 통한 보정은 단위 차이로 인한 거친 오류를 해결해 주지만, 모든 데이터 문제를 자동으로 증명하지는 못합니다.
- 근미래/근과거 경계 데이터의 모호성: 타임스탬프 생성 시점이 기점(1970년) 부근인 과거 데이터이거나 자릿수가 특이한 구간에서는 자릿수 휴리스틱만으로 단위를 100% 확정할 수 없으므로 반드시 데이터 원천의 명세 확인이 병행되어야 합니다.
- 윤초 및 서머타임 차이: 윤초가 반영되는 시스템과 일반 POSIX 타임스탬프 사이의 미세한 초 오차, 또는 서머타임 변경 시점의 모호성은 단순 단위 변환만으로는 검증할 수 없습니다.
- 텍스트 파싱 오류: 데이터 자체가 정수가 아니라 빈 문자열이나 부적절한 기호로 들어온 경우는 빈칸·0·null 차이: 데이터 정리 전에 확인할 것에서 다루는 사전 정제 단계가 선행되어야 합니다.
참고 자료와 확인 범위
아래 자료는 형식·기능의 정의를 확인하는 데 사용했습니다. 본문의 예제와 설명은 이 사이트의 작업 상황에 맞춰 구성했습니다. 제품 메뉴는 버전과 언어에 따라 다를 수 있습니다.
확인일: 2026-10-19 · 오류를 발견하면 이 글의 오류 신고로 알려주세요.