JavaScript中的日期间隔计算 [英] Date interval calculation in JavaScript

查看:88
本文介绍了JavaScript中的日期间隔计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个函数来计算输入日期(以年,月和日为止)之间的时间间隔以及现在的日期。我需要能够从过去或未来的输入日期,以闰年为单位,并且以多年,几个月(幸运的是我每个月可以使用30天)和单个对象的天数返回并使其全部工作在一个更大的功能,我可以在输入日期调用。我花了这么多时间,基本上是使用UTC时间计算间隔时间,计算闰年,并为每个闰年添加天数,然后使用我的值创建一个字典,但经过这么多的工作,我感觉我还是有不准确之处当我转换值&通过加1个月计算(如果是24个月或更高的时间,我会遇到问题)照顾月数> 12。在过去的两天里,我曾经在这方面做过很多工作。感觉像我已经清理了我以前的问题,但仍然不完全正确我觉得像我的计算中有一些缺陷...这是我的代码:

  var timeInterval = function(inputYear,inputMonth,inputDay){

var intervalInDays = function(inputYear,inputMonth,inputDay){
var now = new Date();
var then = new Date(inputYear,(inputMonth - 1),inputDay);
var now_utc = new Date(now.getUTCFullYear(),now.getUTCMonth() now.getUTCDate());
var then_utc = new Date(then.getUTCFullYear(),then.getUTCMonth(),then.getUTCDate());
var intervalInMill = then_utc - now_utc;
var intervalInDays =(intervalInMill /(1000 * 60 * 60 * 24));
返回Math.abs(Math.round(intervalInDays));
///返回Math.round(intervalInMill /( 1000 * 60 * 60 * 24));
};

var countLeapYears = function(inputYear,inputMonth,inputDay){
var yearNow = new Da te()。getFullYear(),
yearThen = inputYear,
beginYear = 0,
endYear = 0,
leapYearCount = 0;

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

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

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

return leapYearCount;
};

var totalDays = intervalInDays(inputYear,inputMonth,inputDay);
var leapYearCount = countLeapYears(inputYear,inputMonth,inputDay);
var years = Math.abs(Math.trunc(totalDays / 365));
var months = Math.abs(Math.trunc((totalDays - ((years * 365) - leapYearCount))/ 30));
if(months> = 12){
years + = 1;
months = months - 12;
}
var days = Math.abs(totalDays - (years * 365) - (months * 30) - leapYearCount);

///Math.abs((totalDays - ((years * 365) - leapYearCount))%30);

var intervalDict = {
年:年,
月:月,
天:天,
};
return intervalDict;
};

console.log(timeInterval(2014,11,3));
console.log(timeInterval(2016,2,5));
console.log(timeInterval(2015,2,5));
console.log(timeInterval(2005,2,5));
console.log(timeInterval(1982,3,10));


解决方案

这不是100%准确但非常接近

  Date.prototype.diff = function(y,m,d){
var cleanDate = function(x){
x.setHours(0);
x.setMinutes(0);
x.setSeconds(0);
return x;
}

var dateToCompare = new Date(y,m,d),
date = cleanDate(this),
daysCount = [31,28,31, 30,31,30,31,31,30,31,30,31],
d =(date> dateToCompare?date:dateToCompare),
d1 =(date< dateToCompare?date:dateToCompare ),
days = 0,
months = 0,
years = 0;

var yearDiff = function(){
years = d.getFullYear() - (d1.getFullYear()+ 1);
years = years< 0? 0:年
}

var monthDiff = function(){
months = d.getFullYear()== d1.getFullYear()? (d.getMonth() - 1) - d1.getMonth():d.getMonth()+(12 - (d1.getMonth()+ 1));
if(months> = 12){
years = years + Math.floor(months / 12)
months = months%12;
}
}

var getAdjustedDays = function(){
var adjustedDays = 0;
for(i =(d1.getMonth()+ 1); i< = 12; i ++){
if(daysCount [i] == 31){
adjustedDays ++;
}
}
返回调整日期;
}

var dayDiff = function(){
var month = d1.getMonth();
if(month == 1&&& month == 0&&&年== 0){
days = d.getDate() - d1.getDate();
} else if(month == 1){
days =(isLeapYear(d1.getFullYear())?29 - d1.getDate():28 - d1.getDate())+ d.getDate ()+(d1.getDate()== d.getDate()?1:2);
days = Math.ceil(days - (getAdjustedDays()/ 2));
} else {
days =(daysCount [month] -d1.getDate())+ d.getDate()+(d1.getMonth()== d.getMonth()?2:1) ;
days = Math.ceil(days - (getAdjustedDays()/ 2));
}
getAdjustedDays();
if(days> = 30){
months = months + Math.floor(days / 30); //平均为30天
天=天%30;
}
}

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

yearDiff();
monthDiff();
dayDiff();

return {years:years,months:months,days:days};
}


console.log(new Date()。diff(1987,2,4));
console.log(new Date()。diff(2005,8,25));
console.log(new Date()。diff(2018,8,25));


I'm writing a function to calculate the time interval between an input date in years, months and days and the date now. I need to be able to take an input date from the past or the future, to account for leap years and to return it all in years, months (luckily I can use 30 days per months as an average) and days in a single object and to have it all work in one larger function that I can call on an input date. I've spent So much time on this, basically, I calculate the interval in days using UTC time, account for leap year and add days for each leap year that passed and then create a dictionary using my values but after so much work, I feel like I still have inaccuracies & that there could probably be a problem at the end when I'm converting the values & taking care of if months is > 12 by adding 1 to year count (I feel like if it was 24 months or higher that I'd run into problems). I've worked alot on this in the past 2 days & feel like I"ve cleared up Alot of my prior problems but it's still not completely right I feel like & feel like there are some flaws in my calculations... Here's my code:

var timeInterval = function(inputYear, inputMonth, inputDay) {

  var intervalInDays = function(inputYear, inputMonth, inputDay) {
    var now = new Date();
    var then = new Date(inputYear, (inputMonth - 1), inputDay);
    var now_utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
    var then_utc = new Date(then.getUTCFullYear(), then.getUTCMonth(), then.getUTCDate());
    var intervalInMill = then_utc - now_utc;
    var intervalInDays = (intervalInMill / (1000 * 60 * 60 * 24));
    return Math.abs(Math.round(intervalInDays));
    ///return Math.round(intervalInMill / (1000 * 60 * 60 * 24));
  };

  var countLeapYears = function(inputYear, inputMonth, inputDay) {
    var yearNow = new Date().getFullYear(),
      yearThen = inputYear,
      beginYear = 0,
      endYear = 0,
      leapYearCount = 0;

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

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

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

    return leapYearCount;
  };

  var totalDays = intervalInDays(inputYear, inputMonth, inputDay);
  var leapYearCount = countLeapYears(inputYear, inputMonth, inputDay);
  var years = Math.abs(Math.trunc(totalDays / 365));
  var months = Math.abs(Math.trunc((totalDays - ((years * 365) - leapYearCount)) / 30));
  if (months >= 12) {
  years += 1;
  months = months - 12;
  }
  var days = Math.abs(totalDays - (years * 365) - (months * 30) - leapYearCount);  

  ///Math.abs((totalDays - ((years * 365) - leapYearCount)) % 30);

  var intervalDict = {
    "years": years,
    "months": months,
    "days": days,
  };
  return intervalDict;
};

console.log(timeInterval(2014, 11, 3));
console.log(timeInterval(2016, 2, 5));
console.log(timeInterval(2015, 2, 5));
console.log(timeInterval(2005, 2, 5));
console.log(timeInterval(1982, 3, 10));

解决方案

Well this is not 100% accurate but very close

Date.prototype.diff = function(y,m,d){
    var cleanDate = function(x){
        x.setHours(0);
        x.setMinutes(0);
        x.setSeconds(0);
        return x;
    }

    var dateToCompare = new Date(y,m,d),
        date = cleanDate(this),
        daysCount = [31,28,31,30,31,30,31,31,30,31,30,31],
        d = (date > dateToCompare ? date : dateToCompare),
        d1 = (date < dateToCompare ? date : dateToCompare),
        days = 0,
        months = 0,
        years = 0;

    var yearDiff = function(){
       years = d.getFullYear() - (d1.getFullYear() + 1);
       years = years < 0 ? 0 : years;
    }

    var monthDiff = function(){
        months = d.getFullYear() == d1.getFullYear() ? (d.getMonth() - 1) - d1.getMonth() : d.getMonth() + (12 - (d1.getMonth() + 1));
        if(months >= 12){
            years = years + Math.floor(months / 12)
            months = months % 12;
        }
    }

    var getAdjustedDays = function(){
        var adjustedDays = 0;
        for(i = (d1.getMonth() + 1); i <= 12; i++){
            if(daysCount[i] == 31){
                adjustedDays++;
            }
        }
        return adjustedDays;
    }

    var dayDiff = function(){
         var month = d1.getMonth();
        if(month == 1 && months == 0 && years == 0){
             days = d.getDate() - d1.getDate();
        }else if(month == 1){
            days = (isLeapYear(d1.getFullYear()) ? 29 - d1.getDate() : 28 - d1.getDate()) + d.getDate() + (d1.getDate() == d.getDate() ? 1 : 2);
            days = Math.ceil(days - (getAdjustedDays() / 2));
       }else{
            days = (daysCount[month] - d1.getDate()) + d.getDate() + (d1.getMonth() == d.getMonth() ? 2 : 1);
           days = Math.ceil(days - (getAdjustedDays() / 2));
       } 
       getAdjustedDays();
       if(days >= 30){
           months = months + Math.floor(days / 30); //averge are 30 days
           days = days % 30;
       }
   }  

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

   yearDiff();
   monthDiff();
   dayDiff();

   return {"years" : years, "months" : months, "days" : days};
}


console.log(new Date().diff(1987, 2, 4));
console.log(new Date().diff(2005, 8, 25));
console.log(new Date().diff(2018, 8, 25));

这篇关于JavaScript中的日期间隔计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆