본문 바로가기

👩🏻‍💻Frontend/JavaScript

javascript를 이용한 D-day 계산기 만들기! (feat.수능)

 

수업 시간에 배웠던 기념일 계산기를 활용해 수능 D-day 안내 페이지를 만들어 보기로 했다.

 

 

일단 결과 화면!  

 

캘린더에 디데이 남은 날이 표시되고 그 아래에 시간까지 카운팅 되도록 제작했다.

 

 

 

코드를 살펴보도록 하자!

 

 

변수 선언

const now = new Date();
const test = new Date('2023-11-16') // 2023 수학능력시험 날짜

 

우선 Data 객체를 생성자로 호출해 현재 날짜와 시험 날짜를 담는 변수를 각각 선언해 준다.

( Date 객체는 1970년 1월 1일 UTC(협정 세계시) 자정과의 시간 차이를 밀리초로 나타내는 정숫값을 담는다)

 

Date - JavaScript | MDN

JavaScript Date 객체는 시간의 한 점을 플랫폼에 종속되지 않는 형태로 나타냅니다. Date 객체는 1970년 1월 1일 UTC(협정 세계시) 자정과의 시간 차이를 밀리초로 나타내는 정수 값을 담습니다.

developer.mozilla.org

 

 

 

수능까지 남은 일 수 계산

// 수능까지 남은 일 수 계산
const timeDiff = test.getTime() - now.getTime();

const daysUntilTest = Math.floor(timeDiff / (24 * 60 * 60 * 1000));
document.getElementById('dDay').innerHTML = 'D - ' + daysUntilTest;

 

수능일까지 남은 일 수를 작성하는 코드는 위와 같다. 시간 차이를 담는 변수 timDiff를 선언하고 그 공간에 기준시에서 수능일까지의 시차에서 오늘까지의 시차를 뺀 값을 담는다. 아래의 이미지를 보면 이해가 쉽다.

 

 

시간 차이는 ms로 반환되기 때문에 남은 일 수가 될 수 있게 나눠주는 작업이 필요하다. 하루를 ms로 계산하면 다음과 같다.  하루 = 24시간 =  24*60분 = 24*60*60초 =  24*60*60*1000밀리 초!

시간 차이를 담는 변수 timDiff를 24*60*60*1000밀리 초로 나눠주면 남은 일수가 계산되는데 소수점이 있는 형태로 출력돼 Math.floor 메서드를 사용해 소수점 이하 숫자를 버림 해준다.

 

나는 달력에 크게 디데이가 보이는 부분의 id를 dDay로  설정했기 때문에 getElementById() 메서드를 사용해 해당 요소를 불러오고, Element 속성(property) innerHTML을 사용해 변수 daysUntilTest의 값을 화면에 출력해 줬다.

 

 

 

수능까지 남은 시간 계산

// 남은 시간 표시하기


const remainTime = document.querySelector("#time");

function time() {


    const diff = test - now;

    const diffDay = Math.floor(diff / (1000 * 60 * 60 * 24));
    // console.log(diff)
    // console.log((diff / (1000 * 60 * 60 * 24) + 1))

    const diffHour = Math.floor(((diff / (1000 * 60 * 60)) - 9) % 24);
    const diffMin = Math.floor((diff / (1000 * 60)) % 60);
    const diffSec = Math.floor((diff / 1000) % 60);

    remainTime.innerHTML = `11월 16일까지 ${diffDay}일 ${diffHour}시간 ${diffMin}분 ${diffSec}초`;
    now.setSeconds(now.getSeconds() + 1);
}

time();
setInterval(time, 1000);

 

수능까지 남은 시간이 1초씩 줄어들도록 제작하고 싶었다. 1초에 한 번씩 동기화가 가능하도록 함수를 만든 뒤 setInterval 메서드를 사용해 호출했다. 함수 안에 now.setSeconds(now.getSeconds() + 1);를 넣지 않으면 변경된 시간이 적용되지 않아 시간이 늘어나도록 명령을 추가해 줬다. ( 혼자 해결 못 해서 도움을 받았다. 아직도 왜 setInterval로만 시간 변경을 할 수 없었는지 모르겠다.)

 

time 함수 안에는 시간 차이를 담는 변수 diff를 선언해 처음에 선언했던 변수인 test와 now의 차이를 담았다. 그리고 diff를 사용해 시간, 분, 초를 표시할 수 있도록 수식을 작성했다.

 

시간은 계속 9시간이 차이가 나서 왜 그럴까 했는데 협정세계시(UTC)와 한국 표준시가 9시간이 차이 나서 그런 게 아닐까 싶다. 그래서 9를 빼줬다. 시간 수식 설명을 하자면 (1000*60*60)은 1시간을  ms로 나타내 것이다. diff를 (1000*60*60)로 나누면 남은 시간이 반환된다. 반환된 시간에서 차이가 나는 9시간을 빼준 다음 24시간 안에서의 시간만 보여주기 위해 24로 나눈 시간의 나머지를 출력하도록 한다. (24시간으로 나눴을 때의 몫은 남은 일 수 이다) 분, 초도 같은 방식으로 계산하면 되기에 추가 설명은 생략하겠다.

 

그리고 마지막으로 querySelector로 불러온 위치를 담은 remainTime변수에 innerHTML을 사용해 넣어준다. 그럼 캘린더 하단 부분에 작게 표시되며 카운팅 되는 것을 확인할 수 있다.

 

 

 

D-100, D-50, D-30 표시

// D - 100 표시
const day100 = new Date(test.getTime() - 100 * (1000 * 60 * 60 * 24));
const day100Date = day100.getFullYear() + '.' + (day100.getMonth() + 1) + '.' + day100.getDate();
document.getElementById('day100').innerHTML = day100Date;



// D - 50 표시
const day50 = new Date(test.getTime() - 50 * (1000 * 60 * 60 * 24));
const day50Date = day50.getFullYear() + '.' + (day50.getMonth() + 1) + '.' + day50.getDate();
document.getElementById('day50').innerHTML = day50Date;


// D - 30 표시
const day30 = new Date(test.getTime() - 30 * (1000 * 60 * 60 * 24));
const day30Date = day30.getFullYear() + '.' + (day30.getMonth() + 1) + '.' + day50.getDate();
document.getElementById('day30').innerHTML = day30Date;

 

각각 남은 일수에 해당하는 변수를 하나씩 만들어 해당일까지의 시간 차이를 담았다. 연, 월, 일을 나타내는 메서드를 사용해 각각 표기해 줬다. 월을 담는 메서드는 반환값이 0~11이다. 1을 더해야 해당 월이 된다.

 

 

 

사용한 메서드 및  함수

메서드 or 함수 or 요소 속성 특징
new Date() 1970년 1월 1일 UTC(협정 세계시) 자정과의 시간 차이를 밀리초로 나타내는 정수 값을 담는다.
getTime() 1970년 1월 1일 00:00:00 UTC로부터의 경과시간을 밀리초 단위로 반환. Date가 기준 시간 이전을 나타낼 경우 음수 값을 반환.
getFullYear() Date에서 현지 시간 기준 연도(네 자리 연도면 네 자리로)를 반환.
getMonth() Date에서 현지 시간 기준 월(011)을 반환.
getDate() Date에서 현지 시간 기준 일(131)을 반환.
Math.floor() 주어진 숫자와 같거나 작은 정수 중에서 가장 큰 수를 반환
getElementById() 주어진 문자열과 일치하는 id 속성을 가진 요소를 찾고, 이를 나타내는 객체를 반환
innerHTML 요소 내에 포함된 HTML 또는 XML 마크업을 가져오거나 설정
setSeconds() 현지 Date시간에 따라 이 날짜의 초를 변경
getSeconds() 현지 Date시간에 따라 이 날짜의 초를 반환
setInterval() 각 호출 사이에 고정된 시간 지연으로 함수를 반복적으로 호출하거나 코드 스니펫을 실행
querySelector() 제공한 선택자 또는 선택자 그룹과 일치하는 문서 내 첫 번째 요소를 반환. 일치하는 요소가 없으면 null을 반환