본문 바로가기
개발일지/개발일지! error out🙅

[Planner App/JS] D-day 생성하기

by -제이리 2022. 3. 14.
728x90
320x100

html의 input date타입을 사용하여 D-day 생성기능을 구현하고 싶었다.

 

구글링시 대다수가 아래와 같은 방식으로 알려주는데 내가 해보면 계속 NaN가 나왔다. 😭

function diffDay() {
    const masTime = new Date("yyyy-mm-dd");
    const todayTime = new Date();
    
    const diff = masTime - todayTime;
    
    const diffDay = Math.floor(diff / (1000*60*60*24));
}

 

 


 

이렇게 해보고 저렇게 해봐도 오류가 나서

다른 방법이 없을까 물색하던중 이 글을 참고하기로 했다.

출처: www.codegrepper.com/code-examples/javascript/how+to+count+number+of+days+from+two+date+object+in+js

 

function dDay(){
    const leftDay = inputDate.value
    const date = new Date();

    const year = String(date.getFullYear());
    const month =String(date.getMonth()+1).padStart(2, "0");
    const day =String(date.getDate()).padStart(2, "0");
    const result = `${year}-${month}-${day}`;
    
    const diffDays = (today, otherDate)=> Math.ceil(Math.abs(today-otherDate)/ (1000 * 60 * 60 * 24));

    const diffResult = diffDays(new Date(leftDay), new Date(result));


    if(leftDay == date){
         diffResult = 'D-Day';
    }else if(leftDay < date){
        diffResult = `D+${diffResult}`; 
    }else{
        diffResult = `D-${diffResult}`;
    }
    
    return diffDays
}

결과는 어찌저찌 잘 돌아가긴 했다. 처음에는 html 인풋의 value값과 new Date()를 통해 가져온 값의 형태가 다르게 표현돼서 작동이 잘 안되는 줄 알고 저렇게 년월일 변수를 선언해줬었다.

 

하지만 굳이 그렇게 안해도 돌아가고 Math.abs도 빼도 될것같아 조금씩 수정해주니 코드도 줄고 잘돌아갔다.

function dDay(){
    const leftDay = inputDate.value
    const date = new Date();
    
    const diffDays = (today, otherDate)=> Math.floor((otherDate-today)/ (1000 * 60 * 60 * 24));

    const diffResult = diffDays(new Date(leftDay), date);


    if(diffResult == 0){
        return 'D-Day';
    }else if(diffResult < 0){
        return `D${diffResult}`; 
    }else{
        return `D+${diffResult}`;
    }
}

하지만 아직도 복잡하고 가독성이 좋지 않았다.


처음에 시도했다 실패했던 코드를 다시보니 문제점이 이제서야 눈에 들어왔다.

 

처음에는 변수선언을 이렇게 주었었는데 
const leftDay = inputDate.value;
 
 

new Date()를 사용해서 수정해주니 더이상 NaN이 나오지 않게되었다.. (이렇게 간단한걸 놓쳐서.. 밥오....)

Date함수를 사용해야 날짜 연산이 가능해진다.

const leftDay = new Date(inputDate.value);

 

 

최종적으로 수정한 깔끔한 코드.

삼항조건 연산자도 연습해봤다. 이론수업에서 들었던걸 직접 써보니 매우 효율적이라는걸 체감했다.  if else도 안써도 되고 코드도 짧아졌다.  굿! 

(https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)

function dDay(){
    const leftDay = new Date(inputDate.value); //디데이 지정
    const date = new Date(); // 오늘날짜 
    
    const diffResult = date - leftDay;

    const diffDays = Math.floor(diffResult/(1000*60*60*24));

    return (diffDays == 0 ? 'D-DAY' 
    : diffDays < 0 ? `D${diffDays}` 
    : `D+${diffDays}`);
    
}

 

 

 

<최종  d-day js 코드>

const inputTitle = document.querySelector('.input-title');
const inputDate = document.querySelector('.date');
const dDayForm = document.querySelector('.d-day-form');
const dDayBox = document.querySelector('.d-daybox');
const addBtn = document.querySelector('.add-btn');
const cancel = document.querySelector('.cancel');


const DDAYS_KEY = 'D-Day';
const HIDDEN_CLASS = 'form-hidden'

let dDays = [];

function saveDdays(){
    localStorage.setItem(DDAYS_KEY, JSON.stringify(dDays) );
}



function dDay(){
    const leftDay = new Date(inputDate.value);
    const date = new Date();
    
    const diffResult = date - leftDay;

    const diffDays = Math.floor(diffResult/(1000*60*60*24));

    return (diffDays == 0 ? 'D-DAY' 
    : diffDays < 0 ? `D${diffDays}` 
    : `D+${diffDays}`);
    
}


function deleteDday(event) {
    const li = event.target.parentElement;
    li.remove();
    dDays = dDays.filter(Dday => Dday.id !== parseInt(li.id));
    saveDdays();
}

function printDday(newDdayTitle){
    const li = document.createElement('li');
    li.id = newDdayTitle.id;
    const span = document.createElement('span');
    const h2 = document.createElement('h2')
    const button = document.createElement('button');

    span.innerText = newDdayTitle.title;
    h2.innerText = newDdayTitle.Dday;
    button.innerText = '×';

    li.appendChild(span);
    li.appendChild(h2);
    li.appendChild(button);

    dDayBox.appendChild(li);

    button.addEventListener('click', deleteDday);
}

function dDaySubmit(event){
    event.preventDefault();
    const newDdayTitle = inputTitle.value;
    const newDdayDate = dDay()

    const dDayObj = {
        title: newDdayTitle,
        Dday: newDdayDate,
        id: Date.now(),
    }

    inputTitle.value = ''; 
    dDays.push(dDayObj)
    printDday(dDayObj);
    saveDdays();

    dDayForm.classList.add(HIDDEN_CLASS);
}

function formHidden(){
    dDayForm.classList.toggle(HIDDEN_CLASS);
}

dDayForm.addEventListener('submit', dDaySubmit);
cancel.addEventListener('click',formHidden);
addBtn.addEventListener('click',formHidden);


const savedDdays = localStorage.getItem(DDAYS_KEY);

if (savedDdays !== null){
    const parsedDdays = JSON.parse(savedDdays);
    dDays = parsedDdays;
    parsedDdays.forEach(printDday);
}
728x90
320x100

댓글