Как учитывать високосные годы при определении разницы между двумя датами с помощью Javascript?

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

Мне удалось настроить счетчик для определения секунд между двумя точками, разделив результаты на годы, дни, часы, минуты, секунды, используя следующий код:

var lastDay = new Date("Jan 1, 1994  00:00:01").getTime(); 
var x = setInterval(function() { 
var now = new Date().getTime(); 
var t = now - lastDay; 
var years = Math.floor(t / (1000 * 60 * 60 * 24)/ 365);
var days = Math.floor((t % (1000 * 60 * 60 * 24 * 365))/(1000 * 60 * 60 * 24)); 
var hours = Math.floor((t % (1000 * 60 * 60 * 24))/(1000 * 60 * 60)); 
var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)); 
var seconds = Math.floor((t % (1000 * 60)) / 1000); 
document.getElementById("year").innerHTML =years ; 
document.getElementById("day").innerHTML =days ; 
document.getElementById("hour").innerHTML =hours; 
document.getElementById("minute").innerHTML = minutes;  
document.getElementById("second").innerHTML =seconds;  
if (t < 0) { 
        clearInterval(x); 
        document.getElementById("demo").innerHTML = "TIME UP"; 
        document.getElementById("year").innerHTML ='0'; 
        document.getElementById("day").innerHTML ='0'; 
        document.getElementById("hour").innerHTML ='0'; 
        document.getElementById("minute").innerHTML ='0' ;  
        document.getElementById("second").innerHTML = '0'; } 
}, 1000);

Проблема, с которой я столкнулся, заключается в том, что он не учитывает високосные годы, поэтому число «дней» является неточным. Следует добавить еще 7 дней, чтобы учесть количество високосных лет между установленной датой и текущей датой (на момент написания).

Я попытался использовать следующий код для подсчета високосных лет:

var countLeapYears = function(){
  var yearNow = new Date().getFullYear(); 
    var then = new Date("Jan 1, 1994 00:00:01");
    var yearThen = then.getFullYear();
    var beginYear = 0;
    var endYear = 0;
    var leapYearCount = 0;

    var isLeapYear = function(year){
      return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);
    }

    if(yearNow < y){
       beginYear = yearNow;
       endYear = yearThen;
    }else if(yearNow > yearThen){
       beginYear = yearThen;
       endYear = yearNow;
    }else if(yearNow == yearThen){
       beginYear = yearThen;
       endYear = yearThen;
    }

    for(i = beginYear; i <= endYear; i++){
      if(isLeapYear(i)){
        leapYearCount++;
      }
    }

    return leapYearCount;
}

Затем я попытался добавить «leapYearCount» к «дням», но это не удалось:

var countLeapYears = function(){
  var yearNow = new Date().getFullYear(); 
    var then = new Date("Jan 1, 1994 00:00:01");
    var yearThen = then.getFullYear();
    var beginYear = 0;
    var endYear = 0;
    var leapYearCount = 0;

    var isLeapYear = function(year){
      return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);
    }

    if(yearNow < y){
       beginYear = yearNow;
       endYear = yearThen;
    }else if(yearNow > yearThen){
       beginYear = yearThen;
       endYear = yearNow;
    }else if(yearNow == yearThen){
       beginYear = yearThen;
       endYear = yearThen;
    }

    for(i = beginYear; i <= endYear; i++){
      if(isLeapYear(i)){
        leapYearCount++;
      }
    }

    return leapYearCount;
}

var lastDay = new Date("Jan 1, 1994 00:00:01").getTime(); 
var x = setInterval(function() { 
var now = new Date().getTime(); 
var t = now - lastDay; 
var years = Math.floor(t / (1000 * 60 * 60 * 24)/ 365);
var days = Math.floor((t % (1000 * 60 * 60 * 24 * 365))/(1000 * 60 * 60 * 24) + leapYearCount); 
var hours = Math.floor((t % (1000 * 60 * 60 * 24))/(1000 * 60 * 60)); 
var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)); 
var seconds = Math.floor((t % (1000 * 60)) / 1000); 
document.getElementById("year").innerHTML =years ; 
document.getElementById("day").innerHTML =days ; 
document.getElementById("hour").innerHTML =hours; 
document.getElementById("minute").innerHTML = minutes;  
document.getElementById("second").innerHTML =seconds;  
if (t < 0) { 
        clearInterval(x); 
        document.getElementById("demo").innerHTML = "TIME UP"; 
        document.getElementById("year").innerHTML ='0'; 
        document.getElementById("day").innerHTML ='0'; 
        document.getElementById("hour").innerHTML ='0'; 
        document.getElementById("minute").innerHTML ='0' ;  
        document.getElementById("second").innerHTML = '0'; } 
}, 1000);

Любые идеи, как я могу исправить это и добавить дополнительные дни для учета количества прошедших високосных лет?

Большое спасибо.


person Chris    schedule 02.02.2021    source источник
comment
По этому поводу уже много-много вопросов, например. Разница между двумя датами в годах, месяцах, дней в JavaScript и Как получить разницу двух дат в формате mm-dd-hh в Javascript и этот ответ.   -  person RobG    schedule 03.02.2021
comment
Много вопросов, но ни один из них конкретно не касается этого вопроса. Следовательно, задавая вопрос с более подробной информацией и некоторым примером кода. Мне просто нужно было проверить, что у меня есть. Ответы на связанные вопросы тоже не сработали. Спасибо, в любом случае.   -  person Chris    schedule 05.02.2021
comment
Если ваш конкретный вопрос заключается в том, как определить количество високосных лет между двумя датами, это вопрос, отличный от заголовка вопроса и вступительного заявления. Алгоритм floor(years ÷ 4) + 1) не работает точно во многих случаях, например. Период с 1 марта 1996 г. по 28 февраля 2004 г. содержит 1 високосный день, но алгоритм возвращает 3.   -  person RobG    schedule 05.02.2021
comment
Прочитайте весь пост. Вопрос очень ясен   -  person Chris    schedule 06.02.2021


Ответы (1)


Ответ оказался намного проще, чем я думал раньше.

Поскольку я просто пытался учесть разницу в днях из-за високосного года, мне просто нужно было разделить количество лет на 4 и добавить 1, например:

var lastDay = new Date("Jan 1, 1994 10:00:00").getTime(); 
var x = setInterval(function() { 
var now = new Date().getTime(); 
var t = now - lastDay; 
var years = Math.floor(t / (1000 * 60 * 60 * 24)/ 365);
var leapDays = Math.floor((years / 4) + 1);
var days = Math.floor((t % (1000 * 60 * 60 * 24 * 365))/(1000 * 60 * 60 * 24) - leapDays); 
var hours = Math.floor((t % (1000 * 60 * 60 * 24))/(1000 * 60 * 60)); 
var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)); 
var seconds = Math.floor((t % (1000 * 60)) / 1000); 
document.getElementById("year").innerHTML =years ; 
document.getElementById("day").innerHTML =days ; 
document.getElementById("hour").innerHTML =hours; 
document.getElementById("minute").innerHTML = minutes;  
document.getElementById("second").innerHTML =seconds;  
if (t < 0) { 
        clearInterval(x); 
        document.getElementById("demo").innerHTML = "TIME UP"; 
        document.getElementById("year").innerHTML ='0'; 
        document.getElementById("day").innerHTML ='0'; 
        document.getElementById("hour").innerHTML ='0'; 
        document.getElementById("minute").innerHTML ='0' ;  
        document.getElementById("second").innerHTML = '0'; } 
}, 1000);

person Chris    schedule 04.02.2021
comment
Вышеприведенное просто выдает ошибки в Safari. Алгоритм для високосных лет ошибочен. Для периода с 1 марта 1896 г. по 28 февраля 1904 г. он возвращает 2 дополнительных дня, когда в этом периоде нет високосных лет. (Math.floor((new Date(1904,1,28)-new Date(1896,2,1))/8.64e7/365)/4|0)+1. Точно так же период с 1 марта 1996 г. по 28 февраля 2004 г. содержит 1 високосный год, но алгоритм возвращает 3. - person RobG; 05.02.2021
comment
Я запускаю это как в сафари, так и в хроме без проблем. Ответы верны для каждого варианта даты, которую я пробовал. - person Chris; 06.02.2021