Javascript 倒计时不正确

Javascript countdown time incorrect

我的 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/

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>

问题是您没有正确计算小时和分钟。假设您想在 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来封装数字前是否显示零的逻辑)