Tutorial
JavaScript 타임스탬프 전체 가이드
소개
JavaScript는 날짜 및 타임스탬프 작업을 위해 Date 개체를 제공합니다. JavaScript에서 타임스탬프를 적절하게 사용하는 방법을 이해하는 것은 웹 개발, 데이터 처리 및 시간 기반 애플리케이션에 필수적입니다. 이 가이드에서는 타임스탬프 기본 사항, 변환, 시간대 처리 및 모범 사례를 다룹니다.
JavaScript 타임스탬프 이해하기
JavaScript의 Unix 타임스탬프
JavaScript는 1970년 1월 1일 00:00:00 UTC(Unix 시대) 이후 Unix 타임스탬프를 밀리초 단위로 사용합니다.
JavaScript Timestamp = Milliseconds since 1970-01-01 00:00:00 UTC
Example: 1704624000000
= 1704624000 seconds since epoch
= January 8, 2024, 12:00:00 PM UTC
중요: JavaScript는 밀리초를 사용하는 반면 다른 많은 시스템은 초를 사용합니다. 변환할 때는 항상 단위를 확인하세요.
현재 타임스탬프
// Current timestamp in milliseconds
const nowMs = Date.now();
console.log(nowMs); // e.g., 1704624000000
// Alternative method
const nowMs2 = new Date().getTime();
console.log(nowMs2); // Same as Date.now()
// Convert to seconds
const nowSec = Math.floor(Date.now() / 1000);
console.log(nowSec); // e.g., 1704624000
날짜 만들기
날짜 객체 생성
타임스탬프에서
// Create from milliseconds timestamp
const dateFromMs = new Date(1704624000000);
console.log(dateFromMs.toISOString()); // "2024-01-08T12:00:00.000Z"
// Create from seconds timestamp (multiply by 1000)
const dateFromSec = new Date(1704624000 * 1000);
console.log(dateFromSec.toISOString()); // "2024-01-08T12:00:00.000Z"
날짜 구성 요소에서
// Create from year, month, day (months are 0-indexed!)
const date1 = new Date(2024, 0, 8); // January 8, 2024
console.log(date1.toISOString()); // "2024-01-08T00:00:00.000Z"
// Create with time
const date2 = new Date(2024, 0, 8, 14, 30, 0);
console.log(date2.toISOString()); // "2024-01-08T14:30:00.000Z"
// Create from string (ISO 8601 recommended)
const date3 = new Date('2024-01-08T14:30:00.000Z');
console.log(date3.toISOString()); // "2024-01-08T14:30:00.000Z"
일반적인 실수: JavaScript 월은 0부터 인덱스됩니다(0 = 1월, 11 = 12월)!
현재 날짜 및 시간
const now = new Date();
console.log(now.toISOString()); // "2024-01-08T12:34:56.789Z"
console.log(now.toString()); // "Mon Jan 08 2024 07:34:56 GMT-0500"
console.log(now.toDateString()); // "Mon Jan 08 2024"
console.log(now.toTimeString()); // "07:34:56 GMT-0500"
console.log(now.toLocaleString()); // "1/8/2024, 7:34:56 AM"
날짜 구성 요소 가져오기
날짜 부분 추출
const date = new Date(2024, 0, 8, 14, 30, 45, 123);
// Get components
console.log(date.getFullYear()); // 2024
console.log(date.getMonth()); // 0 (January - 0-indexed!)
console.log(date.getDate()); // 8 (day of month)
console.log(date.getHours()); // 14 (hour 0-23)
console.log(date.getMinutes()); // 30 (minutes 0-59)
console.log(date.getSeconds()); // 45 (seconds 0-59)
console.log(date.getMilliseconds()); // 123 (milliseconds 0-999)
// Get day of week (0 = Sunday, 6 = Saturday)
console.log(date.getDay()); // 1 (Monday)
// Get UTC components
console.log(date.getUTCFullYear()); // 2024
console.log(date.getUTCHours()); // 19 (if local is 14:30)
상대 시간 구성 요소
const date = new Date(2024, 0, 8);
// Get timezone offset (in minutes)
const offset = date.getTimezoneOffset();
console.log(offset); // e.g., -300 (UTC-5 = -5 * 60)
// Get timestamp
const timestamp = date.getTime();
console.log(timestamp); // e.g., 1704672000000 (milliseconds)
// Get ISO 8601 string
const isoString = date.toISOString();
console.log(isoString); // "2024-01-08T00:00:00.000Z"
날짜 구성 요소 설정
날짜 수정
const date = new Date(2024, 0, 8);
// Set components (returns timestamp)
date.setFullYear(2025);
date.setMonth(11); // December
date.setDate(25);
date.setHours(18);
date.setMinutes(30);
date.setSeconds(45);
date.setMilliseconds(0);
console.log(date.toISOString()); // "2025-12-25T18:30:45.000Z"
// Set UTC components
date.setUTCFullYear(2025);
date.setUTCHours(12);
중요: Set 메소드는 Date 객체가 아닌 타임스탬프를 반환합니다. 조심스럽게 연결하세요.
// Correct: Use same date object
const date = new Date(2024, 0, 8);
date.setDate(15);
date.setMonth(5); // June 15, 2024
// WRONG: Creates new date, loses changes
const date = new Date(2024, 0, 8);
new Date(date).setDate(15); // Original date unchanged!
날짜 산술
시간 더하기 및 빼기
const date = new Date(2024, 0, 8);
// Add 7 days
date.setDate(date.getDate() + 7);
console.log(date.toISOString()); // "2024-01-15T00:00:00.000Z"
// Add 3 hours (3600 * 1000 ms)
date.setTime(date.getTime() + (3 * 3600 * 1000));
console.log(date.toISOString()); // "2024-01-15T03:00:00.000Z"
// Subtract 1 month
date.setMonth(date.getMonth() - 1);
console.log(date.toISOString()); // "2023-12-15T03:00:00.000Z"
// Add 1 year
date.setFullYear(date.getFullYear() + 1);
console.log(date.toISOString()); // "2024-12-15T03:00:00.000Z"
모범 사례: 정확성을 위해 타임스탬프 산술을 사용합니다.
> // Add 1 hour in milliseconds (60 * 60 * 1000)
> const oneHour = 60 * 60 * 1000;
> const newDate = new Date(date.getTime() + oneHour);
>
시간 차이
const date1 = new Date(2024, 0, 8);
const date2 = new Date(2024, 0, 15);
// Difference in milliseconds
const diffMs = date2 - date1;
console.log(diffMs); // 604800000 (7 days in ms)
// Convert to seconds, minutes, hours, days
const diffSec = Math.floor(diffMs / 1000);
const diffMin = Math.floor(diffMs / (1000 * 60));
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
console.log(`${diffDays} days`); // "7 days"
console.log(`${diffHours} hours`); // "168 hours"
날짜 형식 지정
내장 서식
toLocaleString 제품군
const date = new Date(2024, 0, 8, 14, 30, 45);
// Locale-specific formats
console.log(date.toLocaleDateString()); // "1/8/2024"
console.log(date.toLocaleTimeString()); // "2:30:45 PM"
console.log(date.toLocaleString()); // "1/8/2024, 2:30:45 PM"
// With locale options
console.log(date.toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
}));
// "Monday, January 8, 2024"
console.log(date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
}));
// "2024年1月8日"
국제 형식
const date = new Date(2024, 0, 8);
// ISO 8601 (always UTC)
console.log(date.toISOString()); // "2024-01-08T00:00:00.000Z"
// UTC string
console.log(date.toUTCString()); // "Sun, 07 Jan 2024 00:00:00 GMT"
// Date string (local time)
console.log(date.toString()); // "Mon Jan 08 2024 00:00:00 GMT-0500"
모범 사례: 시간대 문제를 방지하려면 API 호출 및 데이터베이스 저장에 항상
toISOString()을 사용하세요.
사용자 정의 형식
// Manual formatting (use Intl.DateTimeFormat for i18n)
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
console.log(formatDate(new Date(2024, 0, 8, 14, 30, 45)));
// "2024-01-08 14:30:45"
권장 사항: 복잡한 형식 지정에는 수동 형식 지정 대신 date-fns, luxon 또는 day.js와 같은 라이브러리를 사용하세요.
시간대 처리
시간대 작업
시간대 정보 가져오기
const date = new Date();
// Get timezone offset (in minutes)
const offset = date.getTimezoneOffset();
console.log(offset); // e.g., -300 (UTC-5) or 300 (UTC+5)
// Convert offset to hours
const offsetHours = offset / 60;
console.log(offsetHours); // -5 or 5
// Get timezone name (browser-specific)
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(timezone); // e.g., "America/New_York"
시간대 간 변환
const date = new Date(2024, 0, 8, 14, 30, 0);
// Convert to different timezone using toLocaleString
const nyTime = date.toLocaleString('en-US', {
timeZone: 'America/New_York',
timeZoneName: 'short'
});
console.log(nyTime); // "1/8/2024, 9:30:00 AM EST"
const tokyoTime = date.toLocaleString('en-US', {
timeZone: 'Asia/Tokyo'
});
console.log(tokyoTime); // "1/8/2024, 11:30:00 PM"
// Extract time components in specific timezone
const tokyoDate = new Date(date.toLocaleString('en-US', {
timeZone: 'Asia/Tokyo'
}));
console.log(tokyoDate.getHours()); // 23 (11 PM)
모범 사례: 내부적으로는 항상 UTC를 사용하여 작업하고 표시용으로만 현지 시간대로 변환하세요.
UTC와 현지 시간
const date = new Date(2024, 0, 8, 14, 30, 0);
// Local time methods
console.log(date.getHours()); // Local hour (e.g., 14 for EST)
console.log(date.getTime()); // Timestamp (same regardless of timezone)
// UTC methods
console.log(date.getUTCHours()); // UTC hour (e.g., 19 for EST)
console.log(date.getUTCDate()); // UTC day of month
구문 분석 날짜
날짜 문자열 구문 분석
날짜 생성자 사용
// ISO 8601 (recommended)
const isoDate = new Date('2024-01-08T14:30:00.000Z');
console.log(isoDate.toISOString()); // "2024-01-08T14:30:00.000Z"
// Short date format (browser-dependent, avoid!)
const shortDate = new Date('01/08/2024');
console.log(shortDate); // May be Jan 8 or Aug 8 depending on locale
// RFC 2822 format
const rfcDate = new Date('Mon, 08 Jan 2024 14:30:00 GMT');
console.log(rfcDate.toISOString()); // "2024-01-08T14:30:00.000Z"
문제: 날짜 구문 분석이 브라우저와 로케일 전반에 걸쳐 일관되지 않습니다.
수동 구문 분석
// Parse ISO 8601 string manually
function parseISOString(isoString) {
const date = new Date(isoString);
if (isNaN(date.getTime())) {
throw new Error('Invalid date string');
}
return date;
}
// Parse custom format (YYYY-MM-DD)
function parseCustomDate(dateString) {
const [year, month, day] = dateString.split('-').map(Number);
return new Date(year, month - 1, day); // months are 0-indexed
}
console.log(parseCustomDate('2024-01-08').toISOString());
// "2024-01-08T00:00:00.000Z"
권장 사항: 안정적인 구문 분석을 위해 date-fns/parse 또는 luxon/DateTime.fromISO와 같은 라이브러리를 사용하세요.
날짜 확인
// Check if date is valid
function isValidDate(date) {
return date instanceof Date && !isNaN(date.getTime());
}
// Examples
const validDate = new Date(2024, 0, 8);
const invalidDate = new Date('invalid');
console.log(isValidDate(validDate)); // true
console.log(isValidDate(invalidDate)); // false
console.log(isNaN(invalidDate.getTime())); // true (NaN)
일반적인 함정
월 인덱싱
// Common mistake: Using 1-12 for months
const date = new Date(2024, 12, 8); // January 2025!
console.log(date.toISOString()); // "2025-01-08T00:00:00.000Z"
// Correct: Use 0-11 for months
const date = new Date(2024, 11, 8); // December 2024
console.log(date.toISOString()); // "2024-12-08T00:00:00.000Z"
시간대 혼란
const date = new Date(2024, 0, 8, 0, 0, 0);
// These produce different values!
console.log(date.getTime()); // 1704672000000 (same)
console.log(date.toString()); // "Mon Jan 08 2024 00:00:00 GMT-0500"
console.log(date.toISOString()); // "2024-01-08T05:00:00.000Z"
// Midnight EST = 5:00 AM UTC
문제: 시간대 정보 없이 날짜를 생성하면 현지 시간으로 가정됩니다.
문자열 구문 분석 불일치
// Different browsers may parse differently
const date1 = new Date('2024-01-08'); // Might be Jan 8 or Jan 1
const date2 = new Date('2024/01/08'); // Might be parsed differently
const date3 = new Date('01-08-2024'); // Very ambiguous!
// Always use ISO 8601
const date = new Date('2024-01-08T00:00:00Z');
console.log(date.toISOString()); // Consistent across all browsers
수학 오버플로우
const date = new Date(2024, 0, 31);
// Add 2 months to Jan 31
date.setMonth(date.getMonth() + 2);
console.log(date.toISOString()); // "2024-03-31T00:00:00.000Z" ✓
// Add 1 month to Jan 31 (February doesn't have 31!)
date.setMonth(date.getMonth() + 1);
console.log(date.toISOString()); // "2024-03-02T00:00:00.000Z" ✓
// JavaScript auto-adjusts overflow
이점: JavaScript는 날짜 오버플로를 자동으로 처리합니다(윤년에 따라 2월 31일 → 3월 2일 또는 3일).
모범 사례
성능
빈번한 날짜 생성 방지
// BAD: Create new Date in loop
for (let i = 0; i < 1000; i++) {
const now = new Date();
// ... operations
}
// GOOD: Create once, reuse
const now = new Date();
const timestamp = now.getTime();
for (let i = 0; i < 1000; i++) {
// ... operations with timestamp
}
비교를 위해 타임스탬프 사용
const date1 = new Date(2024, 0, 8);
const date2 = new Date(2024, 0, 15);
// BAD: Compare Date objects (slow)
if (date1 < date2) { }
// GOOD: Compare timestamps (fast)
if (date1.getTime() < date2.getTime()) { }
// Even better: Use timestamps directly
const ts1 = date1.getTime();
const ts2 = date2.getTime();
if (ts1 < ts2) { }
캐시 시간대 오프셋
// Cache timezone offset (doesn't change during runtime)
const TZ_OFFSET = new Date().getTimezoneOffset() * 60 * 1000;
// Use in conversions
function toLocalTime(timestamp) {
return new Date(timestamp + TZ_OFFSET);
}
console.log(toLocalTime(Date.now()));
데이터 무결성
// Validate before operations
function safeDateOperation(callback) {
try {
const result = callback();
if (isNaN(result.getTime())) {
throw new Error('Invalid date result');
}
return result;
} catch (error) {
console.error('Date operation failed:', error);
return new Date(); // Return current time as fallback
}
}
// Usage
const result = safeDateOperation(() => {
return new Date(invalidInput);
});
스토리지 모범 사례
// Store as ISO 8601 string
function serializeDate(date) {
return date.toISOString();
}
// Deserialize from ISO 8601
function deserializeDate(isoString) {
return new Date(isoString);
}
// Usage in JSON
const data = {
timestamp: Date.now(),
isoDate: new Date().toISOString(),
userCreated: serializeDate(new Date())
};
// Parse from API
const createdDate = deserializeDate(apiResponse.userCreated);
일반적인 작업
유틸리티 기능
하루의 시작/끝
function startOfDay(date) {
const d = new Date(date);
d.setHours(0, 0, 0, 0);
return d;
}
function endOfDay(date) {
const d = new Date(date);
d.setHours(23, 59, 59, 999);
return d;
}
console.log(startOfDay(new Date()).toISOString());
// "2024-01-08T00:00:00.000Z"
한 주의 시작/끝
function startOfWeek(date) {
const d = new Date(date);
const day = d.getDay();
const diff = d.getDate() - day + (day === 0 ? -6 : 1);
d.setDate(diff);
return startOfDay(d);
}
function endOfWeek(date) {
const d = startOfWeek(new Date(date));
d.setDate(d.getDate() + 6);
return endOfDay(d);
}
console.log(startOfWeek(new Date(2024, 0, 8)).toISOString());
// "2024-01-01T00:00:00.000Z" (Monday)
월 시작/말
function startOfMonth(date) {
return new Date(date.getFullYear(), date.getMonth(), 1);
}
function endOfMonth(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0);
}
console.log(startOfMonth(new Date(2024, 0, 15)).toISOString());
// "2024-01-01T00:00:00.000Z"
console.log(endOfMonth(new Date(2024, 0, 15)).toISOString());
// "2024-01-31T00:00:00.000Z"
연령 계산
function calculateAge(birthDate) {
const today = new Date();
const birth = new Date(birthDate);
let years = today.getFullYear() - birth.getFullYear();
const monthDiff = today.getMonth() - birth.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
years--;
}
return years;
}
console.log(calculateAge('1990-06-15'));
// 33 (assuming current date is 2024-01-08)
영업일 계산
function addBusinessDays(startDate, days) {
const result = new Date(startDate);
let addedDays = 0;
while (addedDays < days) {
result.setDate(result.getDate() + 1);
const dayOfWeek = result.getDay();
if (dayOfWeek !== 0 && dayOfWeek !== 6) { // Not weekend
addedDays++;
}
}
return result;
}
console.log(addBusinessDays(new Date(2024, 0, 8), 5).toISOString());
// "2024-01-15T00:00:00.000Z" (skips weekend)
예시 및 사용 사례
카운트다운 타이머
function countdown(targetDate) {
const now = Date.now();
const target = new Date(targetDate).getTime();
const diff = target - now;
if (diff <= 0) {
return { expired: true };
}
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
return {
expired: false,
days,
hours,
minutes,
seconds,
totalMs: diff
};
}
console.log(countdown('2024-12-31'));
// { expired: false, days: 357, hours: 11, minutes: 29, seconds: 12, totalMs: ... }
상대 시간(예: "2시간 전")
function timeAgo(timestamp) {
const now = Date.now();
const diff = now - timestamp;
const seconds = Math.floor(diff / 1000);
if (seconds < 60) return 'just now';
const minutes = Math.floor(seconds / 60);
if (minutes < 60) return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
const days = Math.floor(hours / 24);
if (days < 30) return `${days} day${days !== 1 ? 's' : ''} ago`;
const months = Math.floor(days / 30);
if (months < 12) return `${months} month${months !== 1 ? 's' : ''} ago`;
const years = Math.floor(days / 365);
return `${years} year${years !== 1 ? 's' : ''} ago`;
}
const oneHourAgo = Date.now() - (60 * 60 * 1000);
console.log(timeAgo(oneHourAgo)); // "1 hour ago"
날짜 범위 확인
function isDateInRange(date, startDate, endDate) {
const timestamp = date.getTime();
return timestamp >= startDate.getTime() && timestamp <= endDate.getTime();
}
// Example: Check if date is in Q1 2024
const q1Start = new Date(2024, 0, 1);
const q1End = new Date(2024, 2, 31);
const testDate = new Date(2024, 1, 15);
console.log(isDateInRange(testDate, q1Start, q1End)); // true
console.log(isDateInRange(new Date(2024, 3, 1), q1Start, q1End)); // false
모범 사례 요약
자바스크립트 날짜 체크리스트
✅ Always use ISO 8601 format ('2024-01-08T14:30:00.000Z') for strings
✅ Work with timestamps internally, convert to Date only for display
✅ Use toISOString() for API calls and database storage
✅ Remember months are 0-indexed (0 = January, 11 = December)
✅ Cache timezone offset and Date.now() to avoid repeated calls
✅ Validate dates with isNaN(date.getTime())
✅ Use Intl.DateTimeFormat for i18n-aware formatting
✅ Consider libraries (date-fns, luxon, day.js) for complex operations
✅ Use timestamp arithmetic for precision (add/subtract milliseconds)
✅ Handle date overflow gracefully (JavaScript auto-adjusts)
❌ Don't use locale-specific strings for parsing (inconsistent across browsers)
❌ Don't mix UTC and local methods in same calculation
❌ Don't create Date objects in loops (reuse or use timestamps)
❌ Don't assume browser timezones (always validate with getTimezoneOffset)
❌ Don't rely on automatic string parsing (use ISO 8601)
❌ Don't forget about DST transitions when calculating business days
성능 팁
✅ Cache Date.now() instead of calling repeatedly
✅ Use timestamps for comparisons (faster than Date objects)
✅ Minimize Date object creation in loops
✅ Use Math.floor() instead of bitwise operators for readability
✅ Store timezone offset as constant for repeated calculations
❌ Don't use Date.parse() on non-ISO strings (unreliable)
❌ Don't create Date objects in hot code paths
❌ Don't use toLocaleString() in performance-critical sections
관련 도구
- Unix 타임스탬프 변환기 - Unix 타임스탬프를 날짜로 변환
- 현재 타임스탬프 - 현재 타임스탬프를 여러 형식으로 가져옵니다.
- 타임스탬프 형식 변환기 - 타임스탬프 형식 간 변환
- 자바스크립트 타임스탬프 도우미 - 자바스크립트 관련 예
- UTC/현지 시간 변환기 - UTC와 현지 시간 간 변환
추가 리소스
날짜/시간 요구사항이 복잡한 프로덕션 애플리케이션의 경우 다음과 같은 라이브러리 사용을 고려하세요.
- date-fns: 모듈식, 불변 날짜 유틸리티
- luxon: 시간대를 지원하는 최신 API(Moment.js 제작자 제공)
- day.js: Moment.js의 경량 대안(2KB)
- temporal-polyfill: 향후 TC39 임시 API 제안
기본 날짜는 기본 작업에 충분하지만 라이브러리는 복잡한 사용 사례에 대해 더 나은 인체 공학적 및 시간대 처리 기능을 제공합니다.