Проблема в том, что вы неправильно рассчитываете часы и минуты. Предполагая, что вы хотите завершить 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 для отображения нуля перед числом или нет)