Date

Date (날짜)

JavaScript Date 객체는 플랫폼 독립적인 형식으로 시간상의 단일 순간(moment)을 나타냅니다. Date 객체는 1970년 1월 1일 자정(UTC, epoch) 이후의 밀리초를 나타내는 정수를 캡슐화합니다. 원문은 MDN의 JavaScript 내장 객체 참고 문서입니다.

출처: Date - JavaScript | MDN

본문

JavaScript Date 객체는 플랫폼 독립적인 형식으로 시간상의 단일 순간을 나타냅니다. Date 객체는 epoch(1970년 1월 1일 자정 UTC) 이후의 밀리초를 나타내는 정수를 캡슐화합니다.

참고: Temporal API의 도입으로 Date 객체는 레거시 기능으로 간주됩니다. 새 코드에는 Temporal 사용을 고려하고, 가능하면 기존 코드도 이전(migrate)하는 것이 좋습니다.

epoch, 타임스탬프, 유효하지 않은 날짜

JavaScript 날짜는 근본적으로 epoch(1970년 1월 1일 자정 UTC, UNIX epoch와 동일) 이후 경과한 밀리초 시간으로 지정됩니다. 이 타임스탬프는 시간대에 무관하며(timezone-agnostic) 역사상의 한 순간을 고유하게 정의합니다.

참고: Date 객체의 핵심에 있는 시간 값은 UTC이지만, 날짜와 시간 또는 그 구성 요소를 가져오는 기본 메서드는 모두 로컬(즉 호스트 시스템) 시간대와 오프셋에서 동작합니다.

Date 객체가 표현할 수 있는 최대 타임스탬프는 최대 안전 정수(Number.MAX_SAFE_INTEGER, 9,007,199,254,740,991)보다 약간 작습니다. Date 객체는 epoch 기준으로 최대 ±8,640,000,000,000,000 밀리초, 즉 ±100,000,000일을 나타낼 수 있습니다. 이는 기원전 271821년 4월 20일부터 서기 275760년 9월 13일까지의 범위입니다. 이 범위 밖의 시간을 나타내려는 시도는 Date 객체가 NaN 타임스탬프 값을 보유하게 하며, 이것이 "Invalid Date"입니다.

console.log(new Date(8.64e15).toString()); // "Sat Sep 13 275760 00:00:00 GMT+0000 (Coordinated Universal Time)"
console.log(new Date(8.64e15 + 1).toString()); // "Invalid Date"

날짜에 저장된 타임스탬프와 상호작용할 수 있는 다양한 메서드가 있습니다. getTime()setTime()으로 타임스탬프 값에 직접 상호작용할 수 있습니다. valueOf()[Symbol.toPrimitive]()(숫자 강제 변환 시 자동 호출됨)는 타임스탬프를 반환하여, Date 객체가 숫자 컨텍스트에서 타임스탬프처럼 동작하게 합니다. 모든 정적 메서드(Date.now(), Date.parse(), Date.UTC())는 Date 객체 대신 타임스탬프를 반환합니다. Date() 생성자는 타임스탬프만 단일 인자로 호출할 수 있습니다.

날짜 구성 요소와 시간대 (Date components and time zones)

날짜는 내부적으로 하나의 숫자, 즉 타임스탬프로 표현됩니다. 상호작용할 때 타임스탬프는 구조화된 날짜-시간 표현으로 해석되어야 합니다. 타임스탬프를 해석하는 방법은 항상 두 가지입니다 — 로컬 시간 또는 UTC(세계 시간 표준이 정의한 전역 표준 시간)로. 로컬 시간대는 날짜 객체에 저장되지 않고 호스트 환경(사용자 기기)에 의해 결정됩니다.

참고: UTC는 그리니치 표준시(GMT)와 혼동해서는 안 됩니다. 둘이 항상 같은 것은 아니기 때문입니다.

예를 들어 타임스탬프 0은 역사상 고유한 순간을 나타내지만 두 가지로 해석될 수 있습니다. UTC 시간으로는 1970년 1월 1일 자정이고, 뉴욕(UTC-5)의 로컬 시간으로는 1969년 12월 31일 19:00:00입니다. getTimezoneOffset() 메서드는 UTC와 로컬 시간의 차이를 분 단위로 반환합니다. 시간대 오프셋은 현재 시간대뿐 아니라 Date 객체가 나타내는 시간에도 의존합니다. 일광 절약 시간제(DST)와 역사적 변경 때문입니다. 본질적으로 시간대 오프셋은 Date 객체가 나타내는 시점의, 호스트 환경의 위치에서의 UTC 시간으로부터의 오프셋입니다.

두 그룹의 Date 메서드가 있습니다. 한 그룹은 타임스탬프를 로컬 시간으로 해석해 다양한 날짜 구성 요소를 가져오고 설정하며, 다른 그룹은 UTC를 사용합니다. 구성 요소별 지역/UTC get/set 매핑은 다음과 같습니다.

  • 연도: getFullYear()/setFullYear()getUTCFullYear()/setUTCFullYear()
  • 월: getMonth()/setMonth()getUTCMonth()/setUTCMonth()
  • 일(월 기준): getDate()/setDate()getUTCDate()/setUTCDate()
  • 시: getHours()/setHours()getUTCHours()/setUTCHours()
  • 분: getMinutes()/setMinutes()getUTCMinutes()/setUTCMinutes()
  • 초: getSeconds()/setSeconds()getUTCSeconds()/setUTCSeconds()
  • 밀리초: getMilliseconds()/setMilliseconds()getUTCMilliseconds()/setUTCMilliseconds()
  • 요일: getDay() (set 없음) ↔ getUTCDay() (set 없음)

Date() 생성자는 두 개 이상의 인자로 호출할 수 있는데, 이 경우 각각 로컬 시간의 연도, 월, 일, 시, 분, 초, 밀리초로 해석됩니다. Date.UTC()는 비슷하게 동작하지만 구성 요소를 UTC 시간으로 해석하고, 연도를 나타내는 단일 인자도 받습니다.

참고: Date() 생성자, Date.UTC(), deprecated된 getYear()/setYear()를 포함한 일부 메서드는 두 자리 연도를 1900년대의 연도로 해석합니다. 예를 들어 new Date(99, 5, 24)는 1999년 6월 24일로 해석됩니다(99년 6월 24일이 아니라).

세그먼트가 예상 범위를 넘치거나(overflow) 모자라면(underflow) 보통 더 높은 세그먼트로 "이월(carries over)"되거나 "차용(borrows from)"합니다. 예를 들어 월이 12로 설정되면(월은 0부터 시작하므로 12월은 11) 다음 해의 1월이 됩니다. 일이 0으로 설정되면 이전 달의 마지막 날이 됩니다. 이것은 날짜 시간 문자열 형식으로 지정된 날짜에도 적용됩니다.

로컬 시간대 오프셋 전환(보통 일광 절약 시간제)에 걸치는 로컬 시간을 설정하려고 할 때, 정확한 시간은 Temporal의 "compatible" 옵션과 같은 동작으로 도출됩니다. 즉 로컬 시간이 두 순간에 대응하면 더 이른 것을 선택하고, 로컬 시간이 존재하지 않으면(간격이 있으면) 간격 지속 시간만큼 앞으로 갑니다.

// America/New_York 로컬 시간대 가정
// 2024-03-10 02:30은 봄 전환(spring-forward) 안에 있어 존재하지 않음
console.log(new Date(2024, 2, 10, 2, 30).toString());
// Sun Mar 10 2024 03:30:00 GMT-0400 (Eastern Daylight Time)
// 2024-11-03 01:30은 가을 전환(fall-back) 안에 있어 두 번 존재함
console.log(new Date(2024, 10, 3, 1, 30).toString());
// Sun Nov 03 2024 01:30:00 GMT-0400 (Eastern Daylight Time)

날짜 시간 문자열 형식 (Date time string format)

날짜를 문자열로 형식화하는 방법은 매우 많습니다. JavaScript 사양은 범용적으로 지원되는 형식을 하나만 지정합니다 — ISO 8601 달력 날짜 확장 형식을 단순화한 날짜 시간 문자열 형식입니다. 형식은 다음과 같습니다.

YYYY-MM-DDTHH:mm:ss.sssZ
  • YYYY — 연도. 네 자리(0000~9999) 또는 +/- 뒤에 여섯 자리가 오는 확장 연도. 확장 연도에는 부호가 필요하며, -000000은 유효한 연도로 명시적으로 금지됩니다.
  • MM — 월, 두 자리(01~12). 기본값 01.
  • DD — 월 기준 일, 두 자리(01~31). 기본값 01.
  • T — 문자열의 시간 부분 시작을 나타내는 리터럴 문자. 시간 부분을 지정할 때 필수입니다.
  • HH — 시, 두 자리(00~23). 특수한 경우로 24:00:00이 허용되며 다음 날 자정으로 해석됩니다. 기본값 00.
  • mm — 분, 두 자리(00~59). 기본값 00.
  • ss — 초, 두 자리(00~59). 기본값 00.
  • sss — 밀리초, 세 자리(000~999). 기본값 000.
  • Z — 시간대 오프셋. 리터럴 문자 Z(UTC를 나타냄) 또는 +/- 뒤에 HH:mm(UTC로부터의 시간·분 오프셋).

다양한 구성 요소를 생략할 수 있으므로 다음은 모두 유효합니다.

  • 날짜만: YYYY, YYYY-MM, YYYY-MM-DD
  • 날짜-시간: 위 날짜만 형식 중 하나 뒤에 THH:mm, HH:mm:ss, 또는 HH:mm:ss.sss. 각 조합 뒤에 시간대 오프셋이 올 수 있습니다.

예를 들어 "2011-10-10"(날짜만), "2011-10-10T14:48:00"(날짜-시간), "2011-10-10T14:48:00.000+09:00"(밀리초와 시간대 포함)은 모두 유효한 날짜 시간 문자열입니다.

시간대 오프셋이 없을 때, 날짜만 형식은 UTC 시간으로 해석되고 날짜-시간 형식은 로컬 시간으로 해석됩니다. UTC 시간으로 해석되는 것은 ISO 8601과 일치하지 않았지만 웹 호환성 때문에 변경할 수 없었던 역사적 사양 오류 때문입니다. (Broken Parser – A Web Reality Issue 참고.)

Date.parse()Date() 생성자는 모두 날짜 시간 문자열 형식의 문자열을 입력으로 받아들입니다. 또한 입력이 이 형식과 일치하지 않을 때 구현체는 다른 날짜 형식을 지원할 수 있습니다. toISOString() 메서드는 날짜를 날짜 시간 문자열 형식으로 나타낸 문자열을 반환하며, 시간대 오프셋은 항상 Z(UTC)로 설정됩니다.

참고: 최대 호환성을 위해 입력이 위의 날짜 시간 문자열 형식을 따르도록 하는 것이 권장됩니다. 다른 형식의 지원은 보장되지 않기 때문입니다. 그러나 RFC 2822 형식처럼 모든 주요 구현에서 지원되는 일부 형식이 있고, 그런 경우 사용이 허용될 수 있습니다. 항상 크로스 브라우저 테스트를 수행해 코드가 모든 대상 브라우저에서 동작하는지 확인하세요. 여러 다른 형식을 수용해야 한다면 라이브러리가 도움이 될 수 있습니다.

비표준 문자열은 구현체가 원하는 어떤 방식으로든 파싱할 수 있으며, 시간대도 포함합니다 — 대부분의 구현체는 기본적으로 로컬 시간대를 사용합니다. 구현체는 범위를 벗어난 날짜 구성 요소에 대해 유효하지 않은 날짜를 반환하도록 요구되지는 않지만, 보통은 그렇게 합니다. 문자열이 범위 내 날짜 구성 요소를 가질 수 있지만 실제로 존재하지 않는 날짜를 나타낼 수도 있습니다(예: "2월 30일"). 이 경우 구현체는 일관되지 않게 동작합니다. Date.parse() 페이지에 이러한 비표준 경우에 대한 더 많은 예가 있습니다.

날짜를 형식화하는 다른 방법 (Other ways to format a date)

  • toISOString()1970-01-01T00:00:00.000Z 형식의 문자열을 반환합니다(위에서 소개한 날짜 시간 문자열 형식, 단순화된 ISO 8601). toJSON()toISOString()을 호출하고 그 결과를 반환합니다.
  • toString()Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time) 형식의 문자열을 반환하고, toDateString()toTimeString()은 각각 문자열의 날짜 부분과 시간 부분을 반환합니다. [Symbol.toPrimitive]()("string" 또는 "default" 전달 시)는 toString()을 호출하고 결과를 반환합니다.
  • toUTCString()Thu, 01 Jan 1970 00:00:00 GMT(일반화된 RFC 7231) 형식의 문자열을 반환합니다.
  • toLocaleDateString(), toLocaleTimeString(), toLocaleString()은 보통 Intl API가 제공하는 로케일 특정 날짜·시간 형식을 사용합니다.

생성자 및 정적 메서드 (Constructor and static methods)

  • Date() — 생성자로 호출하면 새 Date 객체를 반환하고, 함수로 호출하면 현재 날짜와 시간의 문자열 표현을 반환합니다.
  • Date.now() — 현재 시간에 대응하는 숫자 값 — 1970년 1월 1일 00:00:00 UTC 이후의 밀리초 수(윤초 무시)를 반환.
  • Date.parse() — 날짜의 문자열 표현을 파싱하고 1970년 1월 1일 00:00:00 UTC 이후의 밀리초 수(윤초 무시)를 반환.
  • Date.UTC() — 생성자의 가장 긴 형태와 같은 매개변수(2~7개)를 받아 1970년 1월 1일 00:00:00 UTC 이후의 밀리초 수(윤초 무시)를 반환.

인스턴스 멤버 (Instance members)

인스턴스 속성 Date.prototype.constructor는 인스턴스 객체를 만든 생성자 함수입니다(Date 인스턴스의 초기값은 Date 생성자).

로컬 시간 get/set 메서드: getDate(), getDay(), getFullYear(), getHours(), getMilliseconds(), getMinutes(), getMonth(), getSeconds(), getTime(), getTimezoneOffset(), getYear()(deprecated, getFullYear() 사용), setDate(), setFullYear(), setHours(), setMilliseconds(), setMinutes(), setMonth(), setSeconds(), setTime(), setYear()(deprecated).

UTC get/set 메서드: getUTCDate(), getUTCDay(), getUTCFullYear(), getUTCHours(), getUTCMilliseconds(), getUTCMinutes(), getUTCMonth(), getUTCSeconds(), setUTCDate(), setUTCFullYear(), setUTCHours(), setUTCMilliseconds(), setUTCMinutes(), setUTCMonth(), setUTCSeconds().

문자열 반환 메서드: toDateString(), toISOString(), toJSON(), toLocaleDateString(), toLocaleString(), toLocaleTimeString(), toString(), toTimeString(), toUTCString(). 그 외 valueOf(), [Symbol.toPrimitive]().

사양 및 호환성

Date는 ECMAScript 사양에서 정의되며, Baseline "Widely available"로 분류되어 2015년 7월부터 브라우저 전반에서 사용 가능했습니다. 기능의 일부 부분은 지원 수준이 각각 다를 수 있습니다.

더 알아보기