JavaScript Date.now(): Unix 타임스탬프 얻고 변환하기
JavaScript Date.now()에 초점을 맞춘 가이드: 현재 Unix 타임스탬프 얻기, 초 대 밀리초 변환, 타임스탬프를 Date 객체로 만들기, Intl로 포맷, 흔한 파싱 함정 피하기.
JavaScript가 시간을 내부적으로 저장하는 방식
모든 JavaScript Date는 내부적으로 Unix 에포크(1970년 1월 1일 00:00:00 UTC) 이후의 밀리초를 나타내는 단일 64비트 부동소수점입니다. 이 숫자가 Date.getTime()과 Date.now()가 반환하는 값입니다. Date 안에는 저장된 시간대가 없습니다 — 항상 UTC 밀리초 카운트입니다. 시간대 정보는 날짜를 표시용으로 포맷할 때만 중요하며, 그래서 같은 Date 객체가 로스앤젤레스에서는 월요일 저녁, 도쿄에서는 화요일 아침으로 보일 수 있습니다. 이 글은 Date.now()와 타임스탬프 변환에 초점을 맞춥니다; JavaScript의 모든 타임스탬프 작업에 대한 더 넓은 설명은 아래 링크된 완전 참조 가이드를 보세요.
현재 Unix 타임스탬프 얻기
밀리초에는 Date.now()를, 초에는 Math.floor(Date.now() / 1000)을 쓰세요. 둘 다 널리 지원되고 import가 필요 없습니다. 중요한 명명 습관은 변수 이름에 단위를 포함하는 것입니다: createdAtMs, expiresAtSeconds, unixSeconds. 단위 이름은 미래의 API 소비자가 단위 없는 타임스탬프 필드의 의미를 추측하는 것을 막습니다.
- Date.now() → 1700000000000 (milliseconds, 13 digits)
- Math.floor(Date.now() / 1000) → 1700000000 (seconds, 10 digits)
- +new Date() → same as Date.now() via unary coercion
- new Date().getTime() → same result, slightly more verbose
Date.now() vs performance.now()
Date.now()는 벽시계 타임스탬프용입니다: 로그, API 페이로드, 데이터베이스 필드, 캐시 만료, 그리고 실제 달력 시간에 맞춰야 하는 모든 것. performance.now()는 현재 페이지나 프로세스 내 경과 시간을 측정하는 용도입니다. 단조롭고 고정밀이지만 Unix 타임스탬프가 아니며 추가 기준점 없이는 실제 날짜로 변환할 수 없습니다.
- 값을 저장하거나 API로 보내거나 날짜로 표시할 때는 Date.now()를 사용
- 렌더링, 파싱, 요청이 얼마나 걸렸는지 측정할 때는 performance.now()를 사용
- performance.now()를 이벤트 시간으로 데이터베이스에 저장하지 말 것
- 보안에 민감한 타이밍을 위해 두 Date.now() 값을 빼지 말 것; 시스템 시계 변경이 영향을 줄 수 있음
타임스탬프를 Date로 변환하기
Date 생성자는 밀리초를 받습니다. 타임스탬프가 초(10자리)라면 넘기기 전에 1000을 곱하세요. 이를 잊는 것이 JavaScript에서 가장 흔한 타임스탬프 실수입니다. 빠른 점검은 자릿수입니다: 현재 Unix 초는 10자리, 현재 Unix 밀리초는 13자리이며, Date 생성자 호출은 13자리 밀리초 형식을 받아야 합니다.
- new Date(1700000000 * 1000) → Tue Nov 14 2023 22:13:20 UTC ✓ correct
- new Date(1700000000) → Tue Jan 20 1970 16:13:20 UTC ✗ missing × 1000
- new Date(1700000000 * 1000).toISOString() → '2023-11-14T22:13:20.000Z'
- new Date(1700000000 * 1000).toUTCString() → 'Tue, 14 Nov 2023 22:13:20 GMT'
Intl로 시간대 인식 포맷
로캘과 시간대를 인식하는 출력에는 Intl.DateTimeFormat을 쓰세요. 일광 절약 시간을 자동으로 처리하고 외부 라이브러리가 필요 없습니다. 대시보드, 관리 도구, 상태 페이지, 사용자 대상 타임스탬프에 가장 안전한 내장 경로입니다. 로캘과 IANA 시간대를 모두 명시적으로 고를 수 있기 때문입니다.
- new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'long' }).format(date)
- date.toLocaleString('en-GB', { timeZone: 'Europe/London', hour12: false })
- date.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
- new Intl.DateTimeFormat('en-CA', { timeZone: tz }).formatToParts(date) → array of {type, value} for custom layouts
날짜 문자열을 안전하게 파싱하기
파싱은 JavaScript가 놀라움을 주는 지점입니다. 명시적 Z나 오프셋이 있는 ISO 문자열은 하나의 정확한 순간을 식별하므로 안전합니다. 헐벗은 날짜와 비공식 문자열은 읽기 쉽지만 종종 브라우저 규칙이나 런타임 시간대에 의존합니다. API 계약에는 시간대가 있는 ISO 8601 문자열이나 단위를 필드 이름에 적은 숫자 Unix 타임스탬프를 선호하세요.
- Safe: new Date('2026-05-19T14:30:00Z') — explicit UTC
- Safe: new Date('2026-05-19T10:30:00-04:00') — explicit offset
- Risky: new Date('05/19/2026') — locale-dependent and ambiguous
- Risky: new Date('2026-05-19 10:30') — not a strict ISO timestamp in all runtimes
JavaScript의 흔한 타임스탬프 실수
- new Date(1700000000 * 1000) 대신 new Date(1700000000) — 2023년이 아니라 1970년에 떨어짐
- getMonth()는 1–12가 아니라 0–11을 반환 — 표시할 때 항상 date.getMonth() + 1을 사용
- new Date('2024-01-01')은 UTC 자정으로, new Date('2024/01/01')은 로컬 자정으로 파싱됨
- '내일'을 위해 86400000ms를 더하면 일광 절약 전환에서 깨짐 — 대신 setDate(d.getDate() + 1)을 사용
- Date 객체를 ===로 비교하면 항상 실패 — 대신 .getTime() 값을 비교
권장 JavaScript 타임스탬프 체크리스트
가장 단순한 프로덕션 패턴은 하나의 정규 순간을 저장하고 가장자리에서만 포맷하는 것입니다. 타임스탬프는 UTC로 유지하고, 이름에 단위를 포함하며, UI나 보고 계층에서만 사람이 읽을 수 있는 시간대로 변환하세요.
- 브라우저 전용 상태와 JavaScript Date 생성에는 Unix 밀리초를 사용
- Unix 시간을 초로 문서화한 API를 호출할 때는 Unix 초를 사용
- 사람이 페이로드를 검사할 수 있을 때는 Z나 명시적 오프셋이 있는 ISO 8601을 사용
- 표시에는 명시적 timeZone과 함께 Intl.DateTimeFormat을 사용
- 로컬 달력 날짜가 중요할 때는 일광 절약 경계 주변에 테스트를 추가
JavaScript 타임스탬프 FAQ
- Date.now()는 초를 반환하나요, 밀리초를 반환하나요?
- Date.now()는 1970년 1월 1일 00:00:00 UTC 이후의 밀리초를 반환합니다. API가 Unix 초를 기대하면 1000으로 나누고 Math.floor()를 쓰세요.
- 왜 new Date(1700000000)이 1970년을 보여주나요?
- Date 생성자는 밀리초를 기대합니다. 1700000000은 초 타임스탬프라서 JavaScript는 에포크 이후 17억 밀리초로만 읽습니다. new Date(1700000000 * 1000)을 쓰세요.
- JavaScript Date는 시간대를 저장하나요?
- 아니요. Date는 UTC 밀리초 카운트를 저장합니다. 시간대는 toString(), toLocaleString(), Intl.DateTimeFormat 같은 메서드로 포맷할 때만 적용됩니다.
- Unix 타임스탬프를 JavaScript Date로 어떻게 변환하나요?
- 생성자에 밀리초를 넘기세요: 10자리 초 값에는 new Date(seconds * 1000), 13자리 밀리초 값에는 new Date(ms). × 1000을 잊는 것이 2023년 타임스탬프가 1970년으로 표시되는 이유입니다.