Language/JavaScript

[모던 JavaScript] 5.11 Date 객체와 날짜

뚜sh뚜sh 2023. 2. 7. 14:01

객체 생성하기

new Date()

let now = new Date();
alert( now ); // 현재 날짜 및 시간이 출력됨

 

new Date(milliseconds)

- UTC 기준 1970년 1월 1일 0시 0분 0초에서 milliseconds 밀리초(1/1000초) 후의 시점이 저장된 Date 객체가 반환됨

- 1970년의 첫날을 기준으로 흘러간 밀리초를 나타내는 정수는 타임스탬프라고 부름

 

new Date(datestring)

let date = new Date("2017-01-26");
alert(date);
// 인수로 시간은 지정하지 않았기 때문에 GMT 자정이라고 가정하고
// 코드가 실행되는 시간대(timezone)에 따라 출력 문자열이 바뀝니다.
// 따라서 얼럿 창엔
// Thu Jan 26 2017 11:00:00 GMT+1100 (Australian Eastern Daylight Time)
// 혹은

 

new Date(year, month, date, hours, minutes, seconds, ms)

- 첫 번째와 두 번째 인수만 필수값임

- year은 반드시 네 자리 숫자여야 함

- month는 0(1월)부터 11(12월)사이의 숫자여야 함

- date는 일을 나타내는데, 값이 없는 경우엔 1로 처리됨

- hours/minutes/seconds/ms에 값이 없는 경우엔 0으로 처리됨

 

 

 

날짜 구성요소 얻기

  • getFullYear() : 연도(네 자릿수)를 반환함
  • getMonth() : 월을 반환함(0~11)
  • getDate() : 일을 반환함(1~31)
  • getHours(), getMinutes(), getSeconds(), getMilliseconds() : 시, 분, 초, 밀리초를 반환함
  • getDay() : 요일의 숫자값을 반환함(일요일(0)~토요일(6))
  • getTime() : 주어진 일시와 1970년 1월 1일 00시 00분 00초 사이의 간격(밀리초 단위)인 타임스탬프를 반환함
  • getTimezoneOffset() : 현지 시간과 표준 시간의 차이(분)를 반환함

 

 

 

날짜 구성요소 설정하기

  • setFullYear(year, [month], [date])
  • setMonth(month, [date])
  • setDate(date)
  • setHours(hour, [min], [sec], [ms])
  • setMinutes(min, [sec], [ms])
  • setSeconds(sec, [ms])
  • setMilliseconds(ms)
  • setTime(milliseconds) : 1970년 1월 1일 00:00:00 UTC부터 밀리초 이후를 나타내는 날짜를 설정

 

 

 

자동 고침

- 범위를 벗어나는 값을 설정하려고 하면 자동 고침 기능이 활성화되면서 값이 자동으로 수정됨

let date = new Date(2013, 0, 32); // 2013년 1월 32일은 없습니다.
alert(date); // 2013년 2월 1일이 출력됩니다.

 

 

 

Date 객체를 숫자로 변경해 시간차 측정하기

- Date 객체를 숫자형으로 변경하면 타임스탬프(date.getTime()을 호출 시 반환되는 값)가 됨

let date = new Date();
alert(+date); // 타임스탬프(date.getTime()를 호출한 것과 동일함)

 

 

 

Date.now()

- 현재 타임스탬프를 반환하는 메서드

- new Date().getTime()과 의미론적으로 동일하지만 중간에 Date 객체를 만들지 않기에 Date.now()를 사용하는 게 더 빠르고 가비지 컬렉터의 일을 덜어준다는 장점이 있음

 

 

 

벤치마크 테스트

- 비교 대상을 두고 성능을 비교하여 시험하고 평가할 때 쓰임

- CPU를 많이 잡아먹는 함수의 신뢰할만한 벤치마크(평가 기준)를 구하려면 상당한 주의가 필요함

- 아래 예시에서 getTime()을 이용한 방법이 형 변환이 없어서 엔진 최적화에 드는 자원이 줄어들어 훨씬 빠름

- 하지만 benchmark가 실행될 땐 사용할 수 있는 CPU 자원이 적었기 때문에 이 벤치마크는 좋지 않음

function diffSubtract(date1, date2) {
  return date2 - date1;
}

function diffGetTime(date1, date2) {
  return date2.getTime() - date1.getTime();
}

function bench(f) {
  let date1 = new Date(0);
  let date2 = new Date();

  let start = Date.now();
  for (let i = 0; i < 100000; i++) f(date1, date2);
  return Date.now() - start;
}

alert( 'diffSubtract를 십만번 호출하는데 걸린 시간: ' + bench(diffSubtract) + 'ms' );
alert( 'diffGetTime을 십만번 호출하는데 걸린 시간: ' + bench(diffGetTime) + 'ms' );

 

- 좀 더 신뢰할만한 벤치마크 테스트를 만들려면 benchmark를 번갈아 가면서 여러 번 돌려야 함

function diffSubtract(date1, date2) {
  return date2 - date1;
}

function diffGetTime(date1, date2) {
  return date2.getTime() - date1.getTime();
}

function bench(f) {
  let date1 = new Date(0);
  let date2 = new Date();

  let start = Date.now();
  for (let i = 0; i < 100000; i++) f(date1, date2);
  return Date.now() - start;
}

let time1 = 0;
let time2 = 0;

// 함수 bench를 각 함수(diffSubtract, diffGetTime)별로 10번씩 돌립니다.
for (let i = 0; i < 10; i++) {
  time1 += bench(diffSubtract);
  time2 += bench(diffGetTime);
}

alert( 'diffSubtract에 소모된 시간: ' + time1 );
alert( 'diffGetTime에 소모된 시간: ' + time2 );

 

- 모던 자바스크립트 엔진은 아주 많이 실행된 코드인 'hot code'를 대상으로 최적화를 수행함

- 위 예시에서 bench를 첫 번째 실행했을 때는 최적화가 잘 적용되지 않기 때문에 아래 코드처럼 메인 반복문을 실행하기 전에 예열용(heat-up)으로 bench를 실행할 수 있음

// 메인 반복문 실행 전, "예열용"으로 추가한 코드
bench(diffSubtract);
bench(diffGetTime);

// 벤치마크 테스트 시작
for (let i = 0; i < 10; i++) {
  time1 += bench(diffSubtract);
  time2 += bench(diffGetTime);
}

 

 

 

Date.parse와 문자열

- 메서드 Date.parse(str)를 사용하면 문자열에서 날짜를 읽어올 수 있음

- 단, 문자열의 형식은 YYYY-MM-DDTHH:mm:ss.sssZ처럼 생겨야 함

  • YYYY-MM-DD : 날짜(연-월-일)
  • "T" : 구분 기호로 쓰임
  • HH:mm:ss.sss : 시:분:초.밀리초
  • 'Z' (옵션) : +-hh:mm 형식의 시간대를 나타냄, Z 한 글자인 경우엔 UTC+0을 나타냄

- Date.parse(str)를 호출하면 문자열과 대응하는 날짜의 타임스탬프가 반환됨

let ms = Date.parse('2012-01-26T13:51:50.417-07:00');

alert(ms); // 1327611110417  (타임스탬프)