유닉스 타임스탬프란? (개발자들이 왜 쓰는가)
유닉스 타임스탬프(Unix timestamp)는 하나의 정수입니다. 1970년 1월 1일 00:00:00 (UTC)부터 지금까지 경과한 초(seconds) 수를 뜻합니다. 그 기준 시점을 유닉스 에포크(Unix epoch)라고 부르며, 그 이후의 시간은 중단 없이 초 단위로 계속 카운트됩니다.
지금 이 순간의 타임스탬프는 대략 1,750,000,000 근처일 겁니다. 이 숫자만으로도 컴퓨터, 데이터베이스, API는 “정확히 어느 순간”을 의미하는지 애매함 없이 이해할 수 있습니다.
왜 1970년일까?
유닉스(Unix)는 1960년대 후반 벨 연구소(Bell Labs)에서 개발됐습니다. 엔지니어들이 시간을 표현하기 위한 고정 기준점이 필요했을 때, 이해하기 쉬운 1970년 1월 1일을 선택했습니다. 새로운 10년의 시작이라 계산하기 편했고, 당시 기준으로도 그리 오래 전이 아니라 실용적으로 “음수 날짜”를 피할 수 있었기 때문입니다.
원칙적으로 정해진 날짜라기보다는 실용적인 선택이었고, 그게 표준으로 굳어졌습니다.
유닉스 타임스탬프가 해결하는 문제
날짜를 사람이 읽는 문자열로 저장하면, 곳곳에서 애매함이 생깁니다.
- 형식(포맷) اختلاف:
03/04/25가 3월 4일인지 4월 3일인지? 1925년인지 2025년인지? - 시간대 혼란: “금요일 오후 3시”는 런던과 도쿄에서 서로 다른 순간을 뜻함
- 로케일 차이: 어떤 나라는 일-월-년, 어떤 나라는 월-일-년 표기를 사용
유닉스 타임스탬프는 이런 문제를 대부분 피합니다. 1711929600은 어디에 있든, 어떤 형식을 선호하든 하나의 명확한 순간을 가리킵니다. 머신은 동일하게 이해하고, 사람은 필요할 때 변환해서 보면 됩니다.
초, 밀리초, 마이크로초
원래 유닉스 타임스탬프는 초 단위입니다. 하지만 시스템마다 해상도가 다를 수 있습니다.
| 형식 | 단위 | 예시 |
|---|---|---|
| Unix (POSIX) | 초(Seconds) | 1711929600 |
JavaScript Date.now() | 밀리초(Milliseconds) | 1711929600000 |
Python time.time() | 초(부동소수) | 1711929600.123 |
| 데이터베이스 타임스탬프 | 종종 마이크로초 | 1711929600000000 |
서로 다른 시스템을 오갈 때 가장 흔한 버그 원인 중 하나가 바로 이 해상도 차이입니다. 예를 들어 JavaScript의 밀리초 타임스탬프를 그대로 Python이나 Go에 넘기면 값이 1,000배 커져 버립니다. 시스템 경계를 넘을 때는 반드시 단위를 확인하세요.
유닉스 타임스탬프 읽고 쓰기
JavaScript / TypeScript
// 현재 타임스탬프(초)
Math.floor(Date.now() / 1000)
// 현재 타임스탬프(밀리초)
Date.now()
// 타임스탬프(초) → Date 객체
new Date(timestamp * 1000)
// Date → 타임스탬프(초)
Math.floor(new Date('2024-04-01').getTime() / 1000)
Python
import time, datetime
# 현재 타임스탬프(부동소수)
time.time()
# 타임스탬프 → datetime
datetime.datetime.fromtimestamp(1711929600)
# datetime → 타임스탬프
datetime.datetime(2024, 4, 1).timestamp()
SQL (PostgreSQL)
-- 현재 타임스탬프
EXTRACT(EPOCH FROM NOW())::int
-- 타임스탬프 → timestamp
TO_TIMESTAMP(1711929600)
시간대는 타임스탬프 자체에 영향을 주지 않는다
이 부분은 자주 오해되는 핵심입니다.
유닉스 타임스탬프는 항상 UTC 기준의 “한 순간”을 나타냅니다. 표시할 때만 로컬 시간대로 변환합니다. 저장할 때는 UTC 값을 저장합니다. 즉, 타임스탬프 자체는 시간대와 무관합니다.
즉:
- 서로 다른 시간대에 있는 두 사용자가 “지금(now)”을 저장해도 같은 타임스탬프가 나옴
- 표시할 때는 각 사용자의 로컬 시간대로 보여줌
- DB에서는 오프셋 보정이 필요 없고, 프레젠테이션 레이어에서만 변환하면 됨
2038년 문제(Year 2038 Problem)
유닉스 타임스탬프를 32비트 signed 정수로 저장하면 최대 2,147,483,647초까지만 셀 수 있는데, 이는 2038년 1월 19일 03:14:07 (UTC)에 해당합니다. 그 이후에는 32비트 카운터가 큰 음수로 “랩(wrap)”되어 버립니다.
여전히 32비트 정수로 타임스탬프를 저장하는 시스템은 이 날짜에 문제를 일으킬 수 있습니다. 다만 대부분의 현대 시스템은 64비트 정수를 사용하고, 이 경우 오버플로우 시점은 2,920억 년 수준이라 실무적으로는 신경 쓸 일이 없습니다.
임베디드 시스템, 레거시 DB, 오래된 C 코드 등을 다룬다면 타임스탬프 저장 방식을 확인해두는 게 좋습니다.
언제 유닉스 타임스탬프를 쓰면 좋을까?
유닉스 타임스탬프가 잘 맞는 경우
- DB에 날짜를 저장할 때, 단순하고 정렬 가능한 정수값이 필요할 때
- 시스템/서비스/API 간 날짜를 주고받을 때
- 이벤트를 시간 순으로 비교하거나 정렬할 때
- 기간/지속시간을 계산할 때(두 타임스탬프를 빼기만 하면 됨)
- 캐시/만료 로직에서 사용할 때(
expires_at = now + 3600)
포맷된 날짜 문자열이 더 나은 경우
- 사용자에게 날짜를 표시할 때
- 사람이 읽어야 하는 로그를 남길 때
- 스프레드시트나 CSV 내보내기처럼 사람이 직접 다루는 경우
빠른 변환표
| 항목 | 초(Seconds) |
|---|---|
| 1분 | 60 |
| 1시간 | 3,600 |
| 1일 | 86,400 |
| 1주 | 604,800 |
| 30일 | 2,592,000 |
| 1년(대략) | 31,536,000 |
Unix Timestamp Converter를 사용하면 타임스탬프를 사람이 읽을 수 있는 날짜로 변환하거나, 날짜를 유닉스 타임스탬프로 즉시 변환할 수 있습니다.


