【问题标题】:How to calculate the number of days between two dates? [duplicate]如何计算两个日期之间的天数? [复制]
【发布时间】:2011-02-07 07:42:00
【问题描述】:
  1. 我正在计算“开始”和“结束”日期之间的天数。例如,如果起始日期是 13/04/2010,截止日期是 15/04/2010,那么结果应该是

  2. 如何使用 JavaScript 获得结果?

【问题讨论】:

    标签: javascript html date


    【解决方案1】:

    这是一个执行此操作的函数:

    function days_between(date1, date2) {
    
        // The number of milliseconds in one day
        const ONE_DAY = 1000 * 60 * 60 * 24;
    
        // Calculate the difference in milliseconds
        const differenceMs = Math.abs(date1 - date2);
    
        // Convert back to days and return
        return Math.round(differenceMs / ONE_DAY);
    
    }
    

    【讨论】:

    • 1.5 天变成 2 天与您的示例?改用 Math.floor
    • 避免使用下限,因为如果范围内的一天由于夏令时而变短,则会给出错误的结果。
    • 为什么总是返回 Thu Jan 01 1970 08:00:00 GMT+0800 (Indochina Time) ??
    【解决方案2】:
    const oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
    const firstDate = new Date(2008, 1, 12);
    const secondDate = new Date(2008, 1, 22);
    
    const diffDays = Math.round(Math.abs((firstDate - secondDate) / oneDay));
    

    【讨论】:

    • 警告:并非所有日子都是 24 小时。如果您的日期范围跨越夏令时更改,您将失去或获得一个小时(通常)。在结果上使用 Math.round()(避免使用地板或天花板)。
    • 事实上,我更喜欢 Math.ceil,因为即使还剩 2.01 天,说还剩 3 天比说还剩 2 天更有意义。
    • @Mark 关于使用 Math.round 的评论已添加到答案代码中。不要再对结果进行四舍五入,就像我认识的人一样......(好吧,是我)
    • 我用 2015-02-1 到 2015-03-01 测试了这个,得到了 31 天。这里有问题......编辑:好的,是的.. javascript 月份是从 0-12 所以如果你从 jquery datepicker 或常规正常日期获取输入,请从月份中减去 1
    • 请注意,此代码在计数时仍会考虑给定日期的 TIME。即检查 1 日下午 3 点和 2 日 00:00:00 之间的天数将产生零天。要解决此问题,请在比较之前将两个日期设置为午夜,即添加:firstDate.setHours(0, 0, 0); secondDate.setHours(0, 0, 0);这样你就可以说 daysBetween(new Date(2016,1,10,15), new Date(2016,1,11)));仍然想出 1 天的差异。
    【解决方案3】:

    这是我使用的。如果您只是减去日期,它将无法跨越夏令时边界(例如 4 月 1 日至 4 月 30 日或 10 月 1 日至 10 月 31 日)。这会减少所有时间以确保您有一天,并通过使用 UTC 消除任何 DST 问题。

    var nDays = (    Date.UTC(EndDate.getFullYear(), EndDate.getMonth(), EndDate.getDate()) -
                     Date.UTC(StartDate.getFullYear(), StartDate.getMonth(), StartDate.getDate())) / 86400000;
    

    作为一个函数:

    function DaysBetween(StartDate, EndDate) {
      // The number of milliseconds in all UTC days (no DST)
      const oneDay = 1000 * 60 * 60 * 24;
    
      // A day in UTC always lasts 24 hours (unlike in other time formats)
      const start = Date.UTC(EndDate.getFullYear(), EndDate.getMonth(), EndDate.getDate());
      const end = Date.UTC(StartDate.getFullYear(), StartDate.getMonth(), StartDate.getDate());
    
      // so it's safe to divide by 24 hours
      return (start - end) / oneDay;
    }
    

    【讨论】:

    • 但是如果你放弃时间等,你为什么还要使用UTC?
    • @RuudLenders 因为 UTC 中的一天总是持续 24 小时,这与其他时间格式不同,所以除以 24 小时是安全的
    【解决方案4】:

    来自我的小日期差计算器:

    var startDate = new Date(2000, 1-1, 1);  // 2000-01-01
    var endDate =   new Date();              // Today
    
    // Calculate the difference of two dates in total days
    function diffDays(d1, d2)
    {
      var ndays;
      var tv1 = d1.valueOf();  // msec since 1970
      var tv2 = d2.valueOf();
    
      ndays = (tv2 - tv1) / 1000 / 86400;
      ndays = Math.round(ndays - 0.5);
      return ndays;
    }
    

    所以你会打电话:

    var nDays = diffDays(startDate, endDate);
    

    (完整来源http://david.tribble.com/src/javascript/jstimespan.html。)

    附录

    可以通过更改这些行来改进代码:

      var tv1 = d1.getTime();  // msec since 1970
      var tv2 = d2.getTime();
    

    【讨论】:

    • 出于某种原因,我不得不从 round 函数中取出 - 0.5 才能正常工作,我认为这是因为自 0 索引以来的月份为负 1
    【解决方案5】:

    这是我的实现:

    function daysBetween(one, another) {
      return Math.round(Math.abs((+one) - (+another))/8.64e7);
    }
    

    +<date> 对整数表示进行类型强制,与<date>.getTime() 具有相同的效果,8.64e7 是一天中的毫秒数。

    【讨论】:

    • 类型强制在这里是多余的,因为您已经使用算术运算符来减去日期(这也会导致类型强制)。所以你可以这样写:Math.round(Math.abs(one - another) / 8.64e7);
    • 2019 年读者:如果您使用的是 typescript,则需要 +
    【解决方案6】:

    我已经为另一个询问如何计算两个日期之间的差异的帖子编写了这个解决方案,所以我分享我准备的内容:

    // Here are the two dates to compare
    var date1 = '2011-12-24';
    var date2 = '2012-01-01';
    
    // First we split the values to arrays date1[0] is the year, [1] the month and [2] the day
    date1 = date1.split('-');
    date2 = date2.split('-');
    
    // Now we convert the array to a Date object, which has several helpful methods
    date1 = new Date(date1[0], date1[1], date1[2]);
    date2 = new Date(date2[0], date2[1], date2[2]);
    
    // We use the getTime() method and get the unixtime (in milliseconds, but we want seconds, therefore we divide it through 1000)
    date1_unixtime = parseInt(date1.getTime() / 1000);
    date2_unixtime = parseInt(date2.getTime() / 1000);
    
    // This is the calculated difference in seconds
    var timeDifference = date2_unixtime - date1_unixtime;
    
    // in Hours
    var timeDifferenceInHours = timeDifference / 60 / 60;
    
    // and finaly, in days :)
    var timeDifferenceInDays = timeDifferenceInHours  / 24;
    
    alert(timeDifferenceInDays);
    

    你可以跳过代码中的一些步骤,我写了它以便于理解。

    您将在此处找到一个运行示例:http://jsfiddle.net/matKX/

    【讨论】:

    • 注意月份是零索引的,所以你应该有new Date(date1[0], --date1[1], date1[2]);。此外,使用 parseInt 将截断毫秒。只需减去日期对象并将差值转换为天更简单:Math.round((date1 - date2) / 8.64e7) 或者如果需要整天而不进行四舍五入,只需截断小数部分:(date1 - date2) / 8.64e7 | 0
    【解决方案7】:

    进行了调整以考虑夏令时差异。试试这个:

      function daysBetween(date1, date2) {
    
     // adjust diff for for daylight savings
     var hoursToAdjust = Math.abs(date1.getTimezoneOffset() /60) - Math.abs(date2.getTimezoneOffset() /60);
     // apply the tz offset
     date2.addHours(hoursToAdjust); 
    
        // The number of milliseconds in one day
        var ONE_DAY = 1000 * 60 * 60 * 24
    
        // Convert both dates to milliseconds
        var date1_ms = date1.getTime()
        var date2_ms = date2.getTime()
    
        // Calculate the difference in milliseconds
        var difference_ms = Math.abs(date1_ms - date2_ms)
    
        // Convert back to days and return
        return Math.round(difference_ms/ONE_DAY)
    
    }
    
    // you'll want this addHours function too 
    
    Date.prototype.addHours= function(h){
        this.setHours(this.getHours()+h);
        return this;
    }
    

    【讨论】:

    • 时区偏移不需要调整,时间值是UTC。如果需要调整时区,可以使用setMinutes() 直接将其应用于分钟,而不是转换为小时并使用setHours()set 方法的参数应该是整数。如果使用setHours 并且偏移量不是小时的偶数倍,则该值将被截断。
    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 2012-02-26
    • 2010-10-07
    相关资源
    最近更新 更多