본문 바로가기
Develop/Web

javascript 배송 기한 설정하기

by 라이프레이서 2021. 5. 31.
반응형

e commerce 서비스를 이용하다 보면, "00시간 00분 00초 내 주문 시 당일 발송"과 같은 문구를 볼 수 있습니다.

이번 포스팅에서는 javascript로 배송 기한 설정 작업을 해보겠습니다.

 

- 오후 3시를 기준으로, 오늘 배송인지 내일 배송인 판별 합니다.

- 다음날이 공휴일 / 주말이라면 다음 영업일을 기준으로 몇일, 몇 시간 이내에 주문 시 발송인지 포함합니다.

 

📌 전체 코드

<script>
  window.onload = function(){
    var info_new_wrap = document.querySelector('.parentElement');//class 이름이 parentElement인 요소
    var timer_below_order_cost = createTimer();
    info_new_wrap.appendChild(timer_below_order_cost);
  }
  
  // Date format -> yyyymmdd
  Date.prototype.yyyymmdd = function() {
    var mm = this.getMonth() + 1; // getMonth() is zero-based
    var dd = this.getDate();
    return [this.getFullYear(),
            (mm>9 ? '' : '0') + mm,
            (dd>9 ? '' : '0') + dd
           ].join('');
  };
  function pad2(n) { return n < 10 ? '0' + n : n }
  function toDate( yyyymmddhhmmss ){
    var year = yyyymmddhhmmss.substring(0, 4);
    var month = yyyymmddhhmmss.substring(4, 6);
    var day = yyyymmddhhmmss.substring(6, 8);
    var hour = yyyymmddhhmmss.substring(8, 10);
    var minute = yyyymmddhhmmss.substring(10, 12);
    var second = yyyymmddhhmmss.substring(12, 14);
    var date = new Date(year, month-1, day, hour, minute, second);
    return date;
  }
  function setCountDownTimer(){
    var today_date = new Date();
    var today_yyyymmdd = today_date.yyyymmdd();
    var today_yyyymmddhhmmss = today_date.getFullYear().toString() + pad2(today_date.getMonth() + 1) + pad2(today_date.getDate()) + pad2(today_date.getHours()) + pad2(today_date.getMinutes()) + pad2(today_date.getSeconds());
    var standard_yyyymmdd = (parseInt(today_yyyymmdd) + 1).toString();
    var standard_yyyymmddhhmmss;
    var standard_day;
    if(isHolidayWeekendCheck(today_yyyymmdd)){
      // 오늘이 휴일이라면
      if(isHolidayWeekendCheck(standard_yyyymmdd)){
        // 다음날이 휴일이라면
         while(isHolidayWeekendCheck(standard_yyyymmdd)){
           standard_yyyymmdd = (parseInt(standard_yyyymmdd) + 1).toString();
         }
        standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
        standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
        countDownTimer(standard_day, "날짜");
      }else{
        // 내일이 평일이라면
        standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
        standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
        countDownTimer(standard_day, "내일");
      }
    }else{
      // 오늘이 평일이라면
      if(today_date.getHours() >= 15){
        // 오후 3시 이후라면
        if(isHolidayWeekendCheck(standard_yyyymmdd)){
          // 다음날이 휴일이라면
           while(isHolidayWeekendCheck(standard_yyyymmdd)){
             standard_yyyymmdd = (parseInt(standard_yyyymmdd) + 1).toString();
           }
          standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
          standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
          countDownTimer(standard_day, "날짜");
        }else{
          // 내일이 평일이라면
          standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
          standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
          countDownTimer(standard_day, "내일");
        }
      }else{
        // 오후 3시 이전
        standard_yyyymmddhhmmss = today_yyyymmdd + "150000"; // 오늘 15시 기준
        standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
        countDownTimer(standard_day, "당일");
      }
    }
  }
  function countDownTimer( standardDate, deliveryType ){
    var countDownDate = standardDate.getTime();
    // Update the count down every 1 second
    var x = setInterval(function() {

      // Get today's date and time
      var now = new Date().getTime();

      // Find the distance between now and the count down date
      var distance = countDownDate - now;

      // Time calculations for days, hours, minutes and seconds
      var days = Math.floor(distance / (1000 * 60 * 60 * 24));
      var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      // var hours = Math.floor(distance / (1000 * 60 * 60));
      var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
      var seconds = Math.floor((distance % (1000 * 60)) / 1000);

      var time_green_text_array = document.querySelectorAll(".time_green_text");
      var time_sub_text2_array = document.querySelectorAll(".time_sub_text2");
      if(days > 0){
        time_green_text_array.forEach(function(element){
          element.innerText = days + "일 " + pad2(hours) + "시간 " + pad2(minutes) + "분 " + pad2(seconds) + "초 ";
        });
      } else{
        time_green_text_array.forEach(function(element){
          element.innerText = pad2(hours) + "시간 " + pad2(minutes) + "분 " + pad2(seconds) + "초 ";
        });
      }
      if(deliveryType === "날짜"){
        // 월, 일
        var standardMonth = pad2(standardDate.getMonth() + 1);
        var standardDay = pad2(standardDate.getDate());
        time_sub_text2_array.forEach(function(element2){
          element2.innerText = standardMonth + "월 " + standardDay + "일 발송";
        });
      }
      if(deliveryType === "내일"){
        time_sub_text2_array.forEach(function(element2){
          element2.innerText = "내일 발송";
        });
      }
      if(deliveryType === "당일"){
        time_sub_text2_array.forEach(function(element2){
          element2.innerText = "당일 발송";
        });
      }
      // If the count down is finished, write some text
      if (distance < 0) {
        clearInterval(x);
        setCountDownTimer();
      }
    }, 1000);
  }
  function createTimer(){
    var timer_container = document.createElement("div");
    var time_green_text = document.createElement("span");
    var time_gray_text = document.createElement("span");
    var time_sub_text2 = document.createElement("span");
    time_green_text.innerText = "00시간 00분 00초";
    time_gray_text.innerText = "내 결제 시";
    time_sub_text2.innerText = "당일 발송";
    
    timer_container.classList.add('timer_container');
    time_green_text.classList.add('time_green_text');
    time_gray_text.classList.add('time_gray_text');
    time_sub_text2.classList.add('time_sub_text2');
    
    timer_container.appendChild(time_green_text);
    timer_container.appendChild(time_gray_text);
    timer_container.appendChild(time_sub_text2);
    return timer_container;
  }
  
 function get_year(src) {
 if ((src < 2021) || (src > 2043 )) {
  return;
 } else {
  return src;
 }
}

function get_month(src) {
 if ((src < 1) || (src > 12 )) {
  return;
 } else {
  return src;
 }
}

function get_day(src,day) {
 if ((src < 1) || (src > day )) {
  return;
 } else {
  return src;
 }
} 
  function lunerCalenderToSolarCalenger ( input_day ) {
 var kk = [
     [1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1],   /* 2021 */
     [2, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2],
     [1, 5, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2],
     [1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1],
     [2, 1, 2, 1, 1, 5, 2, 1, 2, 2, 2, 1],
     [2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2],
     [1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2],
     [1, 2, 2, 1, 5, 1, 2, 1, 1, 2, 2, 1],
     [2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2],
     [1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1],
     [2, 1, 5, 2, 1, 2, 2, 1, 2, 1, 2, 1],   /* 2031 */
     [2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2],
     [1, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 2],
     [1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2, 1],
     [2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2],
     [2, 2, 1, 2, 1, 4, 1, 1, 2, 1, 2, 2],
     [2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2],
     [2, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1],
     [2, 2, 1, 2, 5, 2, 1, 2, 1, 2, 1, 1],
     [2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 2, 1],
     [2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2],   /* 2041 */
     [1, 5, 1, 2, 1, 2, 1, 2, 2, 2, 1, 2],
     [1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2]];

 var md = new Array(31,0,31,30,31,30,31,31,30,31,30,31);

 var year =input_day.substring(0,4);
 var month =input_day.substring(4,6);
 var day =input_day.substring(6,8);

 // 음력에서 양력으로 변환
 var lyear, lmonth, lday, leapyes;
 var syear, smonth, sday;
 var mm, y1, y2, m1;
 var i, j, k1, k2, leap, w;
 var td, y;
 lyear = get_year(year);
 lmonth = get_month(month);

 y1 = lyear - 2021;
 m1 = lmonth - 1;
 leapyes = 0;
 if (kk[y1][m1] > 2)  {
     if (document.frmTest.yoon[0].checked) {
     leapyes = 1;
     switch (kk[y1][m1]) {
        case 3:
        case 5:
          mm = 29;
          break;
        case 4:
        case 6:
          mm = 30;
          break;
      }
     } else {
     switch (kk[y1][m1]) {
       case 1:
       case 3:
       case 4:
         mm = 29;
         break;
       case 2:
       case 5:
       case 6:
         mm = 30;
         break;
     } // end of switch
    } // end of if
 } // end of if

   lday = get_day(day, mm);

   td = 0;
   for (i=0; i<y1; i++) {
   for (j=0; j<12; j++) {
      switch (kk[i][j]) {
        case 1:
          td = td + 29;
          break;
        case 2:
          td = td + 30;
          break;
        case 3:
          td = td + 58;
          break;
        case 4:
          td = td + 59;
          break;
        case 5:
          td = td + 59;
          break;
        case 6:
          td = td + 60;
          break;
        } // end of switch
   } // end of for
 } // end of for

 for (j=0; j<m1; j++) {
  switch (kk[y1][j]) {
    case 1:
      td = td + 29;
      break;
    case 2:
      td = td + 30;
      break;
    case 3:
      td = td + 58;
      break;
    case 4:
      td = td + 59;
      break;
    case 5:
      td = td + 59;
      break;
    case 6:
      td = td + 60;
      break;
  }
  }

  if (leapyes == 1) {
  switch(kk[y1][m1]) {
    case 3:
    case 4:
      td = td + 29;
      break;
    case 5:
    case 6:
      td = td + 30;
      break;
   }
  }

  td =  td + parseFloat(lday) + 22;
  // td : 2021 년 1 월 1 일 부터 원하는 날짜까지의 전체 날수의 합
  y1 = 2020;
  do {
  y1 = y1 +1;
  if  ((y1 % 400 == 0) || ((y1 % 100 != 0) && (y1 % 4 == 0))) {
    y2 = 366;
  }
  else {
    y2 = 365;
  }
  if (td <= y2) {
    break;
  }
  else {
    td = td- y2;
  }
  } while(1);
 
 syear = y1;
 md[1] = parseInt(y2) -337;
 m1 = 0;
 do {
 m1= m1 + 1;
 if (td <= md[m1-1]) {
  break;
 }
 else {
  td = td - md[m1-1];
 }
 } while(1);

 smonth = parseInt(m1);
 sday = parseInt(td);

 // 월이 한자리인경우에는 앞에 0을 붙혀서 반환
 if ( smonth < 10 ) {
  smonth = "0" + smonth;
 }
 // 일이 한자리인경우에는 앞에 0을 붙혀서 반환
 if ( sday < 10 ) {
  sday = "0" + sday;
 }

 return new String( syear + smonth + sday );
}
  function isHoliday( yyyymmdd ) {
 // 검사년도
 var yyyy = yyyymmdd.substring( 0, 4 );
 var holidays = new Array();

 // 음력 공휴일을 양력으로 바꾸어서 입력
 var tmp01 = lunerCalenderToSolarCalenger( yyyy + "0101" );// 음력설날
 var tmp02 = lunerCalenderToSolarCalenger( yyyy + "0815" );// 음력추석
 holidays[0] = tmp01 - 1; // 음력설 첫째날
 holidays[1] = tmp01;   // 음력설 둘째날
 holidays[2] = tmp01 + 1; // 음력설 셋째날
 holidays[3] = tmp02 - 1; // 추석 첫째날
 holidays[4] = tmp02;   // 추석 둘째날
 holidays[5] = tmp02 + 1; // 추석 셋째날 
 holidays[6] = lunerCalenderToSolarCalenger( yyyy + "0408" ); // 석가탄신일

 // 양력 공휴일 입력
 holidays[7] = yyyy + "0101";  // 양력설날
 holidays[8] = yyyy + "0301";  // 삼일절
 holidays[9] = yyyy + "0405";  // 식목일
 holidays[10] = yyyy + "0505";  // 어린이날
 holidays[11] = yyyy + "0606";  // 현충일
 holidays[12] = yyyy + "0717";  // 제헌절
 holidays[13] = yyyy + "0815";  // 광복절
 holidays[14] = yyyy + "1003";  // 개천절
 holidays[15] = yyyy + "1225";  // 성탄절

 for ( var i=0; i<holidays.length ; i++ ) {
  if ( holidays[i] == yyyymmdd ) {
   return true ;
  }
 }
}
 function isWeekend( yyyymmdd ) {
  var yyyy = parseInt( yyyymmdd.substring( 0, 4 ), 10 );
  var mm  = ( parseInt( yyyymmdd.substring( 4, 6 ), 10 ) - 1 );
  var dd  = parseInt( yyyymmdd.substring( 6, 8 ), 10 );
  var date = new Date( yyyy, mm, dd );
 
  if ( date.getDay() == 6 || date.getDay() == 0 ) {
   return true;
  } else {
   return false;
  }
 }
function isHolidayWeekendCheck( yyyymmdd ) {
 if ( isHoliday( yyyymmdd ) || isWeekend( yyyymmdd ) ) {
  return true;
 } else {
  return false;
 }
}
setCountDownTimer();

</script>
<style>
  .timer_container{
    display: flex;
    margin-top: 4px;
    margin-left: 10px;
    margin-bottom: 16px;
  }
  .time_green_text{
    margin-left: 4px;
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: bold;
    font-size: 14px;
    line-height: 20px;
    color: #C00D14;
  }
  .time_gray_text{
    margin-left: 4px;
    font-family: Noto Sans KR;
    font-style: normal;
    font-size: 14px;
    line-height: 20px;
    color: #828282;
  }
  .time_sub_text2{
    margin-left: 4px;
    font-family: Noto Sans KR;
    font-style: normal;
    font-weight: bold;
    font-size: 14px;
    line-height: 20px;
    color: #333333;
  }
</style>

👀 부분적으로 알아보기

👉 타이머 띄우기

 window.onload = function(){
    var info_new_wrap = document.querySelector('.parentElement');//class 이름이 parentElement인 요소
    var timer_below_order_cost = createTimer();
    info_new_wrap.appendChild(timer_below_order_cost);
  }

위 부분은 페이지 로딩이 다 되면 호출됩니다.

지정한 Element의 자식 요소로 Timer를 추가합니다.

 

👉 타이머 만들기

function createTimer(){
    var timer_container = document.createElement("div");
    var time_green_text = document.createElement("span");
    var time_gray_text = document.createElement("span");
    var time_sub_text2 = document.createElement("span");
    time_green_text.innerText = "00시간 00분 00초";
    time_gray_text.innerText = "내 결제 시";
    time_sub_text2.innerText = "당일 발송";
    
    timer_container.classList.add('timer_container');
    time_green_text.classList.add('time_green_text');
    time_gray_text.classList.add('time_gray_text');
    time_sub_text2.classList.add('time_sub_text2');
    
    timer_container.appendChild(time_green_text);
    timer_container.appendChild(time_gray_text);
    timer_container.appendChild(time_sub_text2);
    return timer_container;
  }

주로 Element를 만들고, 자식으로 추가 및 class 추가와 같은 내용입니다.

 

👉 타이머 시간 설정하기

 function setCountDownTimer(){
    var today_date = new Date();
    var today_yyyymmdd = today_date.yyyymmdd();
    var today_yyyymmddhhmmss = today_date.getFullYear().toString() + pad2(today_date.getMonth() + 1) + pad2(today_date.getDate()) + pad2(today_date.getHours()) + pad2(today_date.getMinutes()) + pad2(today_date.getSeconds());
    var standard_yyyymmdd = (parseInt(today_yyyymmdd) + 1).toString();
    var standard_yyyymmddhhmmss;
    var standard_day;
    if(isHolidayWeekendCheck(today_yyyymmdd)){
      // 오늘이 휴일이라면
      if(isHolidayWeekendCheck(standard_yyyymmdd)){
        // 다음날이 휴일이라면
         while(isHolidayWeekendCheck(standard_yyyymmdd)){
           standard_yyyymmdd = (parseInt(standard_yyyymmdd) + 1).toString();
         }
        standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
        standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
        countDownTimer(standard_day, "날짜");
      }else{
        // 내일이 평일이라면
        standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
        standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
        countDownTimer(standard_day, "내일");
      }
    }else{
      // 오늘이 평일이라면
      if(today_date.getHours() >= 15){
        // 오후 3시 이후라면
        if(isHolidayWeekendCheck(standard_yyyymmdd)){
          // 다음날이 휴일이라면
           while(isHolidayWeekendCheck(standard_yyyymmdd)){
             standard_yyyymmdd = (parseInt(standard_yyyymmdd) + 1).toString();
           }
          standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
          standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
          countDownTimer(standard_day, "날짜");
        }else{
          // 내일이 평일이라면
          standard_yyyymmddhhmmss = standard_yyyymmdd + "000000";
          standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
          countDownTimer(standard_day, "내일");
        }
      }else{
        // 오후 3시 이전
        standard_yyyymmddhhmmss = today_yyyymmdd + "150000"; // 오늘 15시 기준
        standard_day = toDate(standard_yyyymmddhhmmss); //기준 날짜를 Date타입으로 변환
        countDownTimer(standard_day, "당일");
      }
    }
  }

타이머를 위해서는 기준이 되는 시간과, 현재 시간의 차이를 계산해야 합니다.

기준 시간은 다음 영업일 오후 3시로 잡았습니다.

이에 따라 어떤 내용을 표시할지 달라지는데, 다음과 같습니다.

🎈 오늘이 휴일이라면

    - 다음날이 휴일이라면

        - 다음 영업일 계산하여 해당 날짜의 오후 3시를 기준 시간으로, 멘트는 00월 00일 발송

    - 다음날이 평일이라면 : 기준 시간은 다음날 오후 3시, 멘트는 '내일' 발송

 

📌 오늘이 평일이라면

- 현재 시간이 오후 3시 이전이라면 : 기준 시간은 오늘 오후 3시, 멘트는 '당일' 발송

- 현재 시간이 오후 3시 이후라면

    - 다음날이 휴일이라면

        - 다음 영업일 계산하여 해당 날짜의 오후 3시를 기준 시간으로, 멘트는 00월 00일 발송

    - 다음날이 평일이라면 : 기준 시간은 다음날 오후 3시, 멘트는 '내일' 발송

 

👉 1초마다 시간 계산하도록 하기

function countDownTimer( standardDate, deliveryType ){
    var countDownDate = standardDate.getTime();
    // Update the count down every 1 second
    var x = setInterval(function() {

      // Get today's date and time
      var now = new Date().getTime();

      // Find the distance between now and the count down date
      var distance = countDownDate - now;

      // Time calculations for days, hours, minutes and seconds
      var days = Math.floor(distance / (1000 * 60 * 60 * 24));
      var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      // var hours = Math.floor(distance / (1000 * 60 * 60));
      var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
      var seconds = Math.floor((distance % (1000 * 60)) / 1000);

      var time_green_text_array = document.querySelectorAll(".time_green_text");
      var time_sub_text2_array = document.querySelectorAll(".time_sub_text2");
      if(days > 0){
        time_green_text_array.forEach(function(element){
          element.innerText = days + "일 " + pad2(hours) + "시간 " + pad2(minutes) + "분 " + pad2(seconds) + "초 ";
        });
      } else{
        time_green_text_array.forEach(function(element){
          element.innerText = pad2(hours) + "시간 " + pad2(minutes) + "분 " + pad2(seconds) + "초 ";
        });
      }
      if(deliveryType === "날짜"){
        // 월, 일
        var standardMonth = pad2(standardDate.getMonth() + 1);
        var standardDay = pad2(standardDate.getDate());
        time_sub_text2_array.forEach(function(element2){
          element2.innerText = standardMonth + "월 " + standardDay + "일 발송";
        });
      }
      if(deliveryType === "내일"){
        time_sub_text2_array.forEach(function(element2){
          element2.innerText = "내일 발송";
        });
      }
      if(deliveryType === "당일"){
        time_sub_text2_array.forEach(function(element2){
          element2.innerText = "당일 발송";
        });
      }
      // If the count down is finished, write some text
      if (distance < 0) {
        clearInterval(x);
        setCountDownTimer();
      }
    }, 1000);
  }

나머지는 주말, 공휴일을 체크하고 결괏값으로 받아보는 내용이라, 생략하겠습니다.

 

반응형