코드에서 날짜를 Epoch로 변환해야 할 때
대부분의 앱은 타임스탬프를 Unix 정수로 저장하지만, 입력으로 받는 날짜는 문자열입니다 — 폼의 캘린더 값, CSV의 날짜 컬럼, 특정 타임존으로 포맷된 webhook 필드 등. 이 문자열을 코드에서 epoch로 변환해야 DB가 정렬하고, 서비스가 비교하고, API가 받아들일 수 있습니다. 이 글은 JavaScript, Python, SQL, Go, 셸의 관용적 방법과 어느 팀이든 결국 마주치는 타임존 버그를 다룹니다.
JavaScript: Date, getTime, 타임존 입력
JavaScript는 시간을 밀리초 단위로 저장합니다. Date.UTC는 UTC 벽시계 시각에 대한 밀리초 epoch를 반환하고, 명시 오프셋이 있는 ISO 8601 문자열은 new Date(iso).getTime()으로 처리합니다. 초가 필요하면 1000으로 나눕니다.
- Date.UTC(2026, 0, 1, 0, 0, 0) → 1767225600000 (month is zero-indexed)
- new Date('2026-01-01T08:00:00-05:00').getTime() → 1767265200000
- Math.floor(Date.now() / 1000) → current Unix seconds
- Wall-clock in a non-UTC zone needs a zone-aware library (Luxon, date-fns-tz, Temporal)
Python: datetime.timestamp와 calendar.timegm
Python의 datetime 객체는 .timestamp()로 epoch로 바뀝니다 — 단, 타임존이 붙어 있을 때만요. naive datetime은 호스트의 로컬 타임으로 해석되며, 이것이 프로덕션에서 epoch가 잘못되는 가장 흔한 원인입니다.
- datetime(2026, 1, 1, tzinfo=timezone.utc).timestamp() → 1767225600.0
- calendar.timegm(struct_time) → seconds (UTC-only)
- datetime.now(ZoneInfo('America/New_York')).timestamp() → zone-aware now
- Avoid datetime.fromisoformat(s).timestamp() when s has no offset
SQL: EXTRACT EPOCH, UNIX_TIMESTAMP, UNIX_SECONDS
주요 DB는 모두 타임스탬프 컬럼에서 epoch 정수를 뽑는 함수를 제공합니다. 컬럼의 타임존을 명시적으로 처리하세요: TIMESTAMP WITH TIME ZONE과 TIMESTAMP WITHOUT TIME ZONE은 동작이 매우 다릅니다.
- PostgreSQL: EXTRACT(EPOCH FROM ts) → seconds (double)
- MySQL: UNIX_TIMESTAMP(ts) → seconds, naive ts read in session timezone
- BigQuery: UNIX_SECONDS(ts) / UNIX_MILLIS(ts) — TIMESTAMP only
- SQLite: strftime('%s', ts) → seconds as string, cast to integer
Go와 셸: time.Unix와 date +%s
Go에서는 오프셋이 포함된 layout으로 파싱한 뒤 .Unix()로 초, .UnixMilli()로 밀리초를 얻습니다. 셸에서 GNU date -d는 일반적인 날짜 문자열을 해석하고, BSD/macOS의 date -j -f는 명시 포맷이 필요합니다.
- Go: t, _ := time.Parse(time.RFC3339, "2026-01-01T00:00:00Z"); t.Unix()
- Go: time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC).Unix()
- GNU date: date -d "2026-01-01 00:00:00 UTC" +%s
- macOS date: date -j -u -f "%Y-%m-%d %H:%M:%S" "2026-01-01 00:00:00" +%s
FAQ
- How do I convert time to epoch time?
- Choose the date, clock time, and timezone, then convert that instant to Unix seconds or milliseconds. If the timezone is missing, the result may be off by hours.
- Is timestamp to epoch the same as date to epoch?
- Usually yes. It means converting a readable timestamp or date-time string into an epoch number.
- Should I send epoch seconds or milliseconds to an API?
- Follow the API documentation. If it says Unix timestamp, it often means seconds, but JavaScript-oriented APIs may expect milliseconds.
- Why does the same date give a different epoch in different timezones?
- Because a local wall-clock time only identifies an instant once a timezone is attached. 2026-01-01 00:00 is 1767225600 in UTC but 1767243600 in New York — five hours later in real time. Set the timezone before converting.