JavaScript中的日期间隔计算

时间:2016-02-03 20:42:06

标签: javascript function date datetime dictionary

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

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));

3 个答案:

答案 0 :(得分:1)

简短的回答:您可以使用moment.js而不是重新发明轮子,而您的脚本将在一行中完成:

interval = moment().diff(moment([inputYear, inputMonth, inputDay]))

然后你可以通过interval.days(),interval.months(),interval.years()

访问日/月/年

答案很长:你误解了javascript变量的声明。如果在函数或循环中声明var,它将仅在此上下文中可用。例如,您在years内定义if (intervalInDays > 365),因此在结束}之后,您的变量年份不可用。

在同一个寄存器中,您声明两次intervalInDays,一次在普通函数中,一次在名为intervalInDays的函数内。当你使用它来定义dict时,它实际上会引用函数,而不是它的结果,可能不是你想要的。

在您的第二个示例中,您尝试使用不存在的years变量,因此它显然会失败。

结论:您的变量必须在需要可用的最高级别声明,否则您将无法访问它们。

答案 1 :(得分:0)

首先,我认为你误解了你的输入日期:

timeInterval(2016,2,5)等于2016年, 3月,5。 如果这就是你想要的东西,但我认为你的意思是2016年,二月,5这将是timeInterval(2016年,1,5)。

function timeInterval(inputYear, inputMonth, inputDay) {
    var now = new Date();
    var then = new Date(inputYear, inputMonth, inputDay);
    var dayCount = 0;

    while (now.setHours(1, 3, 3, 7) > then.setHours(1, 3, 3, 7)) {
        then.setDate(then.getDate() + 1);
        dayCount++;
    }
    while (now.setHours(1, 3, 3, 7) < then.setHours(1, 3, 3, 7)) {
        now.setDate(now.getDate() + 1);
        dayCount++;
    }

    var years = Math.floor(dayCount/365);
    dayCount = dayCount - years*365;
    var months = Math.floor(dayCount/30);
    dayCount = dayCount - months*30;
    var days = dayCount;

    return { years, months, days };
}

// this is today: 4th february 2016
console.log(timeInterval(2016, 1, 4));
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));

输出:

{ years: 0, months: 0, days: 0 }
{ years: 1, months: 2, days: 3 }
{ years: 0, months: 1, days: 0 }
{ years: 0, months: 11, days: 6 }
{ years: 10, months: 11, days: 8 }
{ years: 33, months: 10, days: 8 }

仍然不准确,但您声明可以每月30天使用平均值。毕竟它是一个功课,所以试着去理解和改进代码。

答案 2 :(得分:0)

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

10