Unix 타임스탬프란

Unix 타임스탬프(Unix Timestamp)는 1970년 1월 1일 00:00:00 UTC를 기점(Epoch)으로 경과한 시간을 초 단위 정수로 표현한 값입니다. 예를 들어 1711756800은 2024년 3월 30일 00:00:00 UTC를 의미합니다.

이 방식은 1960년대 말 Unix 운영체제 개발 당시 설계되었으며, POSIX 표준(IEEE Std 1003.1)으로 정의되어 현재까지 대부분의 운영체제, 데이터베이스, 프로그래밍 언어의 기본 시간 표현 방식으로 사용됩니다. 타임스탬프는 시간대(Timezone)와 무관한 절대값이기 때문에, 서로 다른 시간대의 시스템 간 시간 동기화와 비교에 이상적입니다.

1970년 1월 1일을 기준으로 선택한 이유는 Unix 시스템 초기 개발 시점인 1969~1970년을 기준으로 설정한 것으로, 당시 32비트 정수로 충분히 표현 가능한 범위를 고려한 실용적 선택이었습니다.

2038년 문제(Y2K38)

32비트 signed integer의 최댓값은 2,147,483,647입니다. Unix 타임스탬프를 32비트 정수로 저장하는 시스템은 이 값에 도달하는 시점, 즉 2038년 1월 19일 03:14:07 UTC에 오버플로가 발생합니다. 이 순간 카운터가 음수로 전환되어 시스템이 1901년 12월 13일로 돌아간 것처럼 동작합니다.

영향 범위는 32비트 Unix/Linux 시스템(임베디드, 구형 서버), MySQL의 TIMESTAMP 타입(내부적으로 32비트 저장, 2038년까지만 지원), PHP의 time() 함수(32비트 시스템에서), 일부 레거시 금융/제조 시스템 등입니다.

64비트 운영체제와 현대적 프로그래밍 언어는 이미 64비트 정수로 타임스탬프를 처리하므로 실질적 문제가 없습니다. 주의가 필요한 영역은 여전히 32비트 TIMESTAMP 타입을 사용하는 레거시 데이터베이스와 임베디드 시스템입니다.

-- 문제: TIMESTAMP는 2038년까지만 지원
CREATE TABLE events (
  created_at TIMESTAMP  -- 32비트 제한
);

-- 해결: DATETIME으로 대체 (64비트, 9999년까지)
CREATE TABLE events (
  created_at DATETIME(3)  -- 밀리초 포함, 9999년까지
);

밀리초 vs 초 단위

Unix 타임스탬프는 원래 초(second) 단위이지만, 현대 시스템에서는 밀리초(millisecond) 단위가 광범위하게 사용됩니다. 이 혼용이 실무에서 혼란의 주요 원인입니다.

언어별 기본 단위: JavaScript의 Date.now()new Date().getTime()밀리초를 반환합니다. Python의 time.time()(float)를 반환합니다. Go의 time.Now().Unix()는 초, time.Now().UnixMilli()는 밀리초를 반환합니다. Unix shell의 date +%s는 초를 반환합니다.

실무 팁으로, 값이 10자리이면 초 단위, 13자리이면 밀리초 단위로 간단히 구분할 수 있습니다. 2001년 9월 9일 이후 초 단위 타임스탬프는 항상 10자리이며, 밀리초 단위는 항상 13자리입니다.

타임존 처리

Unix 타임스탬프 자체는 UTC 절대값이므로 타임존에 독립적입니다. 그러나 사람이 읽을 수 있는 날짜/시간으로 변환할 때 타임존 처리가 필수입니다.

JavaScript의 주의점: new Date(timestamp)로 생성한 Date 객체는 내부적으로 UTC를 저장하지만, toString(), toLocaleString()은 브라우저의 로컬 타임존으로 출력합니다. 서버와 클라이언트가 다른 타임존에 있을 때 혼란이 발생할 수 있습니다. 명시적 타임존이 필요하면 Intl.DateTimeFormattimeZone 옵션을 사용하거나, toISOString()으로 항상 UTC 문자열을 얻으세요.

데이터베이스 저장 권장 방식: UTC로 통일하여 저장하고, 표시 단계에서 사용자 타임존으로 변환하는 방식이 가장 안전합니다. 특히 서머타임(DST)이 있는 국가를 대상으로 하는 서비스에서는 타임존 처리 라이브러리 사용이 필수입니다.

ISO 8601과 타임스탬프 비교

Unix 타임스탬프와 ISO 8601(2024-01-01T00:00:00Z)은 시간을 표현하는 두 가지 주요 방식입니다.

Unix 타임스탬프는 정수 비교로 시간 순서 정렬이 간단하고, 저장 공간이 작으며(32비트 또는 64비트 정수), 타임존 독립적입니다. 반면 ISO 8601은 사람이 직접 읽을 수 있고, 타임존 정보를 문자열 안에 포함할 수 있으며, API 응답과 로그 저장에 널리 권장됩니다.

실무 권장 사항으로, 내부 저장과 연산에는 Unix 타임스탬프, API 응답과 사용자 표시에는 ISO 8601 사용을 권장합니다.

프로그래밍 언어별 사용법

JavaScript: 현재 타임스탬프는 Math.floor(Date.now() / 1000)(초 단위). 타임스탬프 → 날짜는 new Date(timestamp * 1000). ISO 문자열로는 new Date(timestamp * 1000).toISOString().

Python: import time; time.time()으로 현재 타임스탬프 획득. datetime.fromtimestamp(ts, tz=timezone.utc)로 UTC 변환.

Go: time.Now().Unix()로 초 단위 타임스탬프. time.Unix(ts, 0)으로 역변환.

자주 묻는 질문

음수 타임스탬프는 무엇을 의미하나요?

1970년 1월 1일 이전 날짜를 의미합니다. 예를 들어 -86400은 1969년 12월 31일입니다. 64비트 시스템에서는 음수 타임스탬프도 정상적으로 처리됩니다.

JavaScript Date.now()와 Unix 타임스탬프를 혼용하면 왜 문제가 되나요?

Date.now()는 밀리초(13자리), Unix 타임스탬프는 초(10자리)입니다. Date.now() 값을 직접 DB의 TIMESTAMP 컬럼에 저장하거나, 반대로 Unix 타임스탬프를 JavaScript Date 생성자에 바로 넣으면 날짜가 수십 년 어긋납니다. 항상 Math.floor(Date.now() / 1000)으로 변환하거나, new Date(unixTimestamp * 1000)으로 역변환하세요.

2038 문제는 지금 당장 대응해야 하나요?

새로운 프로젝트라면 처음부터 64비트 정수와 DATETIME 타입을 사용하세요. 기존 프로젝트는 MySQL TIMESTAMP 컬럼, 32비트 PHP 환경, 임베디드 시스템을 우선 점검하세요. 64비트 Linux와 현대 언어 런타임은 이미 안전합니다.

도구 활용

Unix 타임스탬프와 날짜를 즉시 변환하려면 타임스탬프 변환기를 사용하세요. 현재 시각의 타임스탬프를 실시간으로 확인하고 UTC/KST/ISO 8601 형식으로 변환할 수 있습니다.

광고 영역