javascript - JavaScript 中的日期间隔计算

标签 javascript function date datetime dictionary

我正在编写一个函数来计算输入日期(以年、月、日为单位)与现在日期之间的时间间隔。我需要能够从过去或 future 获取输入日期,考虑闰年并以年、月为单位返回所有数据(幸运的是,我可以平均每月使用 30 天)和单个对象中的天并让这一切在一个更大的函数中工作,我可以在输入日期调用该函数。我在这上面花了很多时间,基本上,我使用 UTC 时间计算天数间隔,考虑闰年并为每个过去的闰年添加天数,然后使用我的值创建一个字典,但经过这么多工作,我感觉我仍然有不准确的地方,并且当我转换值时,最后可能会出现问题,并通过在年计数中添加 1 来处理月份是否 > 12(我觉得如果是 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));

最佳答案

简短的回答:您可以使用moment.js,而不是重新发明轮子。你的脚本将在一行内结束:

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

然后你可以通过interval.days()、interval.months()、interval.years()访问日/月/年

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

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

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

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

关于javascript - JavaScript 中的日期间隔计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35187290/

相关文章:

javascript - 使用 JavaScript 将 (YYYY/MM/DD HH :MM:SS. MS) GMT 转换为本地时间

javascript - Karma 测试报告运行速度很快,但实际运行速度很慢

我们可以使用头文件而不指定其 .h 扩展名吗

java - 比较Java中的Date对象

javascript - 如何将已声明的 JavaScript 函数指向变量

python - 在不复制代码的情况下访问函数中声明的所有变量

angular - 使用 Angular Reactive Forms 验证年龄是否超过 18 岁

javascript - 如何计算上传的剩余时间?

javascript - angularjs 列表中单个项目的隔离范围

javascript - 如何将 html 元素列表作为参数传递到 Closure 模板中