JavaScript

Date 객체 사용하기

GoJay 2024. 11. 15. 18:38

Date 객체란

자바스크립트는 날짜 형식의 데이터를 처리하기 위한 Date 객체를 별도로 제공한다. Date는 자바스크립트에서 기본 제공하는 빌트인 객체로, Object, Array, String, Number 처럼 생성자(new Date())로 사용된다. Date 생성자로 생성한 값의 타입은 객체다.

const date = new Date();

console.log(date, typeof date) // Fri Nov 15 2024 17:20:49 GMT+0900 (한국 표준시)  'object'

new Date()를 사용하면 Date 객체가 생성되는 시점의 시간을 기준으로 값이 할당된다(사용자 컴퓨터의 기본 로컬 타임존이 그대로 적용된다). 이 값은 정적이며, 시간의 흐름에 따라 값이 계속 변하진 않는다(생성 시점의 값이 정적으로 할당된다).

Date 객체는 UTC 시간(세계 협정 시간) 기준 1970년 1월 1일 0시 0분 0초와 현재 시간까지의 차이를 ms(millisecond) 단위로 환산한 값을 갖는다. 예를 들어서, new Date() 생성자 함수의 인자로 숫자 1000을 입력하면 Thu Jan 01 1970 09:00:01 GMT+0900 (한국 표준시)와 값을 갖는 게 확인된다.

console.log(new Date(1000)) // Thu Jan 01 1970 09:00:01 GMT+0900 (한국 표준시)

참고로, 위에서 살펴봤듯이 생성자 함수에 숫자형 값을 인자로 전달하면 1970년 1월 1일 0시 0분 0초와 전달한 값 사이의 차이를 계산해 날짜를 구해준다. 만약에 임의로 숫자 5000000000을 전달한다면 1970년 1월 1일 0시 0분 0초 기준 5000000000 ms가 경과한 날짜-시간인 Sat Feb 28 1970 05:53:20 GMT+0900 (한국 표준시)가 결과로 확인된다.

문자열 hi를 전달하면 Invalid Date {}라는 결과를 반환한다. 하지만, 날짜로 파싱이 가능한 형태의 문자열(e.g. 2024. 11. 15, 2024-11-15 등)이 전달된다면 정적 메서드 Date.parse()가 동작되어 날짜형 데이터로 값이 반환된다.

console.log(new Date('2024-11-15')) // Fri Nov 15 2024 09:00:00 GMT+0900 (한국 표준시)

이렇게, Date 객체는 날짜와 관련된 객체 데이터를 만들어주고, 날짜 데이터를 처리하기 위한 다양한 정적 메서드와 인스턴스 메서드를 제공해 준다. 하나씩 살펴보자.

Date 객체의 인스턴스 메서드

new Date() 생성자로 만들어진 인스턴스가 사용할 수 있는 메서드는 Date.prototype 객체에 정의되어있다. console.dir로 확인해보면 아래와 같이 정말 많은 프로퍼티들이 정의되어 있는 것이 확인된다.

많은 메서드들 중 활용도가 높은 몇 가지만 살펴보겠다.

연-월-일-요일-시 값 조회하기

Date 객체는 다양한 get 메서드를 갖는다. 그중, getFullYear getMonth getDate getDay getHours getMinutes getSeconds getMilliSeconds 등을 사용하면 필요한 연-월-일-요일-시 값을 가져올 수 있다. 현재의 date 정보를 가져올 수 있도록 Date 객체를 생성해본 후 여러 값들을 get 메서드로 가져와보겠다.

// 아무 인자도 넘겨주지 않으면 사용자 컴퓨터에 설정된 로컬 타임존을 기준으로 생성할 시점의 날짜 정보를 갖게 됨
const date = new Date(); 

console.log(date.getFullYear()) // 2024
console.log(date.getMonth()) // 10
console.log(date.getDate()) // 15
console.log(date.getDay()) // 5
console.log(date.getHours()) // 17
console.log(date.getMinutes()) // 51
console.log(date.getSeconds()) // 17
console.log(date.getMilliseconds()) // 412

값이 숫자로 직관적으로 나온다, 단 getMonth의 결과를 주의하자. 숫자 10이 결과로 나왔지만, 실행 시점은 11월이었다. 즉, getMonth의 결과는 달이 아니라 ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aub', 'Sep', 'Oct', 'Nov', 'Dec']라는 달을 나타내는 배열의 인덱스 값이라고 생각해야 한다. 따라서, 결과 10은 10월이 아니라 달 정보를 담은 배열의 10번째 인덱스인 Nov을 나타낸다는 점 주의하자(date.getMonth() + 1로 값을 사용하면 된다. 단, 12월은 11로 나오지만 그 다음 달은 0이어야 한다는 점을 주의하자).

day도 마찬가지로 ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']라는 배열의 인덱스를 나타낸다고 생각해야 한다. 따라서 값으로 나온 5는 요일의 5번 인덱스인 Fri를 뜻한다. 이때 0번 인덱스가 일요일(Sun)을 나타낸다는 점 주의하자.

연도는 getFullYear를 사용해야 네 자리 수 전체 연도가 나오고, getYear를 사용하면 1900년 기준 경과된 연도 수(2024년이라면 124)가 나온다. new Date()가 1970년 1월 1일 대비 경과된 ms 기준 시간을 나타내는데, getYear는 또 1900년을 기준으로 하기 때문에 값을 사용하는 데 있어 혼란이 생길 수 있다. 각별한 주의가 필요하다.

연-월-일-요일-시 값 설정하기

지정한 Date 객체 값의 연-원-일-요일-시를 조작하고 싶다면 setFullYear setMonth setDate setDay setHours setMinutes setSeconds setMilliseconds를 사용하면 된다. 대표로 setMonthsetDate만 사용해보겠다.

const date = new Date('2024-10-30') // 2024년 11월 30일 00시 00분 00초를 나타냄

date.setMonth(10) // month는 인덱스이기 때문에 10은 11월을 의미
date.setDate(31)

console.log(date) // Sun Dec 01 2024 09:00:00 GMT+0900 (한국 표준시)

결과로 12월 1일이 나왔다. 이는, 10월 30일에서 달을 11월, 일을 31일로 바꿨지만, 11월은 30일까지밖에 없기 때문이다. 이렇게, Date 객체는 일수 조작의 약간의 오류가 생길 경우 알아서 다음 날로 날짜를 넘겨서 값을 반환한다.

날짜 형식 표현하기

날짜는 다양한 방식으로 표현 가능하다. 그리고, Date는 다양한 방식으로 날짜를 표시해 주는 메서드를 갖는다.

const date = new Date();

// Date.prototype.toString은 객체의 Object.prototype.toString 메서드를 재정의해서 사용함
console.log(date.toString()) // Fri Nov 15 2024 18:09:52 GMT+0900 (한국 표준시) 
console.log(date.toDateString()) // Fri Nov 15 2024
console.log(date.toTimeString()) // 18:09:52 GMT+0900 (한국 표준시)
console.log(date.toLocaleString()) // 2024. 11. 15. 오후 6:09:52
console.log(date.toLocaleTimeString()) // 오후 6:09:52

각각이 날짜와 시간을 표시하는 방식과 시간이 다르기 때문에, 필요에 맞게 사용하면 된다. 아니면, 생성한 Date 객체의 값을 get 메서드로 필요한 값을 받아와 원하는 포맷으로 날짜를 표시해주는 커스텀 함수를 사용하는 것도 물론 가능하다.

생성한 Date 객체의 값이 갖는 ms 값(1970년 1월 1일 0시 0분 0초 대비 경과된 ms 값)은 date.valueOf()로 확인 가능하다.

const date = new Date();

console.log(date.valueOf()) // 1731661792545

Date 객체가 표현할 수 있는 ms의 최대-최솟값은 각각 ±8,640,000,000,000,000ms이다. 이는 ±100,000,000일(1억 일)을 의미하며, 기원전 271821년 4월 20일부터 서력 275760년 9월 13일까지를 표현 가능한 범위이다.

Date 객체의 정적 메서드

인스턴스가 아닌, Date 객체 자체에서 갖는 정적 메서드도 존재한다.

Date.now()

코드를 실행한 시점의 시간 값을 1970년 1월 1일 0시 0분 0초 대비 경과된 ms 시간으로 나타내준다.

console.log(Date.now()) // 1731662246488

Date.parse()

정적 메서드 parse는 문자열 날짜 포맷 형태로 입력된 값을 1970년 1월 1일 0시 0분 0초 대비 경과된 ms 시간으로 나타내준다.

console.log(Date.parse('2024-11-15')) // 1731628800000

MDN 문서에 따르면, parse는 브라우저 간 차이 및 일관적이지 못한 동작을 가지고 있기 때문에 사용을 지양하는 것이 좋다고 한다.

Date 객체의 연산

Date 객체의 값들은 서로 더하고 빼는 연산이 가능하다.

let date1 = new Date();
let date2 = '';

setTimeout(() => {
    date2 = new Date()
}, 1000)

date2 - date1 // 1001

아래와 같이, setTimeout으로 1초의 딜레이를 주고 값을 할당하면 두 값 사이의 차가 1001ms로 확인된다. 이는 setTimeout이 실행되는 데 있어 0.001초의 실행 시간이 걸린다는 걸 의미한다.

아래와 같이 두 날짜 사이의 차이를 계산하는 데에도 Date 객체가 사용될 수 있다.

const date1 = new Date('2023-11-15');
const date2 = new Date('2024-11-15');

const diff = date2 - date1

diff // 31622400000

diff는 두 날짜 사이의 ms 시간 간격을 나타낸다. 해당 시간을 31622400000 / (1000 * 60 * 60 * 24) 형태로 계산하면 두 날짜 사이에 366일의 차이가 있음을 알 수 있다.

결론

Date 객체는 사용할 때마다 너무 헷갈려서 정리 차 작성해 봤다. 필요한 시점에 적절하게 잘 활용해 봐야겠다.

'JavaScript' 카테고리의 다른 글

순수 함수에 대해서  (1) 2024.12.06
this 바인딩을 예측하기 어려운 상황 예시  (1) 2024.11.19
프로토타입 톺아보기  (1) 2024.11.13
241102 TIL  (1) 2024.11.03
자바스크립트 엔진과 런타임  (2) 2024.10.30