본문 바로가기
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);
      }

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

     

    반응형