Javascript неверно время обратного отсчета - PullRequest
0 голосов
/ 10 января 2020

У меня проблема с таймером обратного отсчета Jquery. Сценарий ведет обратный отсчет до одного и того же времени каждый день. Время обратного отсчета неверно, это один час. Любые идеи, как это исправить? Он размещен на JSFiddle.

(function($){
  var date    = new Date(),
      month   = date.getMonth();
      day     = date.getDate(),
      weekDay = date.getDay(),
      hours   = {
        start: new Date(date.getFullYear(), month, day),
        end: new Date(date.getFullYear(), month, day)
      };
  
  // weekDay var [0 = sun, 1 = mon, 2 = tues ... 5 = fri 6 = sat]
  
  // If it's Monday - Friday
  if(weekDay >= 1 && weekDay <= 5){

    // Start at 7am, end at 8pm
    hours.start.setHours(7);
    hours.end.setHours(22);

  // If it's Saturday
  } else if(weekDay == 6){

    // Start at 8am, end at 8pm
    hours.start.setHours(8);
    hours.end.setHours(20);

  // If it's Sunday
  } else {

    // Start at 9am, end at 6pm
    hours.start.setHours(9);
    hours.end.setHours(18);
  }

  function countDown(){
    var date         = new Date(),
        countHours   = ('0' + (hours.end.getHours() - date.getHours())).substr(-2),
        countMinutes = ('0' + (59 - date.getMinutes())).substr(-2),
        countSeconds = ('0' + (59 - date.getSeconds())).substr(-2);

    // If it's currently not within the hours, don't show the countdown
    if(date.getHours() < hours.start.getHours() || date.getHours() > hours.end.getHours()){
      $('.countdown').hide();
    } else if($('.countdown').not(':visible')){
      $('.countdown').show();
    }

    $('.countdown .hours').text(countHours);
    $('.countdown .minutes').text(countMinutes);
    $('.countdown .seconds').html(countSeconds);

  }

  $(function(){
    setInterval(function(){
      countDown();
    }, 1000);
  });
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="countdown">
<span class="hours"></span>H <span class="minutes"></span>M <span class="seconds"></span>S
</div>

JSFiddle: http://jsfiddle.net/chrisoliver1990/s1nzydfj/36/

Ответы [ 2 ]

0 голосов
/ 10 января 2020

Проблема в том, что вы неправильно рассчитываете часы и минуты. Предполагая, что вы хотите завершить sh обратный отсчет в 22:00, а сейчас 10:30, тогда это 11 часов 30 минут.

Тем не менее, ваш расчет просто делает hours.end.getHours() - date.getHours(), что, используя значения выше, дает 22 - 10. Это 12, а не 11, потому что код не учитывает полчаса, который уже прошел.

Та же проблема возникает с минутами, но она менее очевидна. Тем не менее, индикация минут отключена на 1, поскольку она не учитывает уже прошедшие секунды.

Вместо этого вам следует использовать другой подход и получить общую разницу в секундах, затем вычислите часы, минуты и секунды, которые представляют:

var end = new Date('2020-01-10T22:00:00');

//let's fake it to 10:30:42
var current = new Date('2020-01-10T10:30:42');

//getTime returns milliseconds, divide by 1000 to get seconds
var differenceInSeconds = Math.floor((end.getTime() - current.getTime()) / 1000);

//for convenience
var secondsInHour = 60 * 60;
var secondsInMinute = 60;


var hours = Math.floor(differenceInSeconds / secondsInHour);

//take the hours out of the difference
differenceInSeconds -= hours * secondsInHour;

var minutes = Math.floor(differenceInSeconds / secondsInMinute);

//take the minutes out of the difference
differenceInSeconds -= minutes * secondsInMinute;

//the rest is just the seconds left
var seconds = differenceInSeconds;

console.log(hours, minutes, seconds);

Добавление этого расчета времени к вашему коду правильно вычисляет оставшееся время:

(function($){
  var date    = new Date(),
      month   = date.getMonth();
      day     = date.getDate(),
      weekDay = date.getDay(),
      hours   = {
        start: new Date(date.getFullYear(), month, day),
        end: new Date(date.getFullYear(), month, day)
      };
  
  // weekDay var [0 = sun, 1 = mon, 2 = tues ... 5 = fri 6 = sat]
  
  // If it's Monday - Friday
  if(weekDay >= 1 && weekDay <= 5){

    // Start at 7am, end at 8pm
    hours.start.setHours(7);
    hours.end.setHours(22);

  // If it's Saturday
  } else if(weekDay == 6){

    // Start at 8am, end at 8pm
    hours.start.setHours(8);
    hours.end.setHours(20);

  // If it's Sunday
  } else {

    // Start at 9am, end at 6pm
    hours.start.setHours(9);
    hours.end.setHours(18);
  }
  
  function formatNumber(num) {
    return ('0' + num).substr(-2);
  }
  
  function countDown(){
    var date         = new Date();
    
    var end = new Date('2020-01-10T22:00:00'),
        differenceInSeconds = Math.floor((hours.end.getTime() - date.getTime()) / 1000);

    //for convenience
    var secondsInHour = 60 * 60;
    var secondsInMinute = 60;

    var countHours = formatNumber(Math.floor(differenceInSeconds / secondsInHour));

    differenceInSeconds -= countHours * secondsInHour;

    var countMinutes = formatNumber(Math.floor(differenceInSeconds / secondsInMinute));

    differenceInSeconds -= countMinutes * secondsInMinute;
    
    var countSeconds = formatNumber(differenceInSeconds);

    // If it's currently not within the hours, don't show the countdown
    if(date.getHours() < hours.start.getHours() || date.getHours() > hours.end.getHours()){
      $('.countdown').hide();
    } else if($('.countdown').not(':visible')){
      $('.countdown').show();
    }

    $('.countdown .hours').text(countHours);
    $('.countdown .minutes').text(countMinutes);
    $('.countdown .seconds').html(countSeconds);

  }

  $(function(){
    setInterval(function(){
      countDown();
    }, 1000);
  });
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="countdown">
<span class="hours"></span>H <span class="minutes"></span>M <span class="seconds"></span>S
</div>

(я также ввел вспомогательную функцию formatNumber для инкапсуляции логики c для отображения нуля перед числом или нет)

0 голосов
/ 10 января 2020

setHours hoursValue параметр основан на 0, поэтому, если вы хотите, чтобы он был 8 вечера, вы устанавливаете его на 19 (не 20). Чек - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours

`

    (function($){
      var date    = new Date(),
          month   = date.getMonth();
          day     = date.getDate(),
          weekDay = date.getDay(),
          hours   = {
            start: new Date(date.getFullYear(), month, day),
            end: new Date(date.getFullYear(), month, day)
          };
      
      // weekDay var [0 = sun, 1 = mon, 2 = tues ... 5 = fri 6 = sat]
      
      // If it's Monday - Friday
      if(weekDay >= 1 && weekDay <= 5){

        // Start at 7am, end at 8pm
        hours.start.setHours(7);
        hours.end.setHours(19);

      // If it's Saturday
      } else if(weekDay == 6){

        // Start at 8am, end at 8pm
        hours.start.setHours(8);
        hours.end.setHours(20);

      // If it's Sunday
      } else {

        // Start at 9am, end at 6pm
        hours.start.setHours(9);
        hours.end.setHours(18);
      }

      function countDown(){
        var date         = new Date(),
            countHours   = ('0' + (hours.end.getHours() - date.getHours())).substr(-2),
            countMinutes = ('0' + (59 - date.getMinutes())).substr(-2),
            countSeconds = ('0' + (59 - date.getSeconds())).substr(-2);

        // If it's currently not within the hours, don't show the countdown
        if(date.getHours() < hours.start.getHours() || date.getHours() > hours.end.getHours()){
          $('.countdown').hide();
        } else if($('.countdown').not(':visible')){
          $('.countdown').show();
        }

        $('.countdown .hours').text(countHours);
        $('.countdown .minutes').text(countMinutes);
        $('.countdown .seconds').html(countSeconds);

      }

      $(function(){
        setInterval(function(){
          countDown();
        }, 1000);
      });
    })(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="countdown">
    <span class="hours"></span>H <span class="minutes"></span>M <span class="seconds"></span>S
    </div>
...