首页 文章

如何获取JavaScript中两个日期之间的天数?

提问于
浏览
315

如何获取JavaScript中两个日期之间的天数?例如,在输入框中给出两个日期:

<input id="first" value="1/1/2000"/>
<input id="second" value="1/1/2001"/>

<script>
  alert(datediff("day", first, second)); // what goes here?
</script>

30 回答

  • 6

    可以计算一个完整的使用以下公式在不同TZ之间休息的两个日期之间的证明天差:

    var start = new Date('10/3/2015');
    var end = new Date('11/2/2015');
    var days = (end - start) / 1000 / 60 / 60 / 24;
    console.log(days);
    // actually its 30 ; but due to daylight savings will show 31.0xxx
    // which you need to offset as below
    days = days - (end.getTimezoneOffset() - start.getTimezoneOffset()) / (60 * 24);
    console.log(days);
    
  • 4

    这是 datediffquick and dirty 实现,作为解决问题中提出的问题的概念证明 . 它依赖于这样一个事实:你可以通过减去它们来获得两个日期之间经过的毫秒数,这会将它们强制转换为它们的原始数值(自1970年开始以来的毫秒数) .

    // new Date("dateString") is browser-dependent and discouraged, so we'll write
    // a simple parse function for U.S. date format (which does no error checking)
    function parseDate(str) {
        var mdy = str.split('/');
        return new Date(mdy[2], mdy[0]-1, mdy[1]);
    }
    
    function datediff(first, second) {
        // Take the difference between the dates and divide by milliseconds per day.
        // Round to nearest whole number to deal with DST.
        return Math.round((second-first)/(1000*60*60*24));
    }
    
    alert(datediff(parseDate(first.value), parseDate(second.value)));
    
    <input id="first" value="1/1/2000"/>
    <input id="second" value="1/1/2001"/>
    

    您应该知道“普通”日期API(名称中没有“UTC”)在用户浏览器的本地时区运行,因此一般情况下,如果您的用户位于您不在的时区,则可能会遇到问题期待,您的代码将不得不处理夏令时转换 . 您应该仔细阅读Date对象及其方法的文档,对于任何更复杂的文档,强烈考虑使用提供更安全和强大的API来进行日期操作的库 .

    另外,为了便于说明,该片段在窗口对象上使用命名访问以简化,但在 生产环境 中,您应该使用标准化的API,如getElementById,或者更可能使用某些UI框架 .

  • 0

    在撰写本文时,只有其中一个答案正确处理DST(夏令时)转换 . 以下是位于加利福尼亚州的系统的结果:

    1/1/2013- 3/10/2013- 11/3/2013-
    User       Formula                      2/1/2013  3/11/2013  11/4/2013  Result
    ---------  ---------------------------  --------  ---------  ---------  ---------
    Miles                   (d2 - d1) / N   31        0.9583333  1.0416666  Incorrect
    some         Math.floor((d2 - d1) / N)  31        0          1          Incorrect
    fuentesjr    Math.round((d2 - d1) / N)  31        1          1          Correct
    toloco     Math.ceiling((d2 - d1) / N)  31        1          2          Incorrect
    
    N = 86400000
    

    尽管 Math.round 返回了正确的结果,但我认为它有些笨重 . 相反,通过在DST开始或结束时明确说明UTC偏移的变化,我们可以使用精确算术:

    function treatAsUTC(date) {
        var result = new Date(date);
        result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
        return result;
    }
    
    function daysBetween(startDate, endDate) {
        var millisecondsPerDay = 24 * 60 * 60 * 1000;
        return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
    }
    
    alert(daysBetween($('#first').val(), $('#second').val()));
    

    解释

    JavaScript日期计算很棘手,因为 Date 对象在UTC内部存储时间,而不是本地时间 . 例如,3/10/2013 12:00 AM太平洋标准时间(UTC-08:00)存储为3/10/2013 8:00 AM UTC和3/11/2013 12:00 AM Pacific Daylight Time( UTC-07:00)存储为3/11/2013 7:00 AM UTC . 在这一天午夜到午夜当地时间只有23小时在UTC!

    虽然当地时间的一天可以有多于或少于24小时,但UTC中的一天总是正好是24小时.1上面显示的 daysBetween 方法利用这一事实,首先调用 treatAsUTC 将本地时间调整为午夜UTC,之前减去和分割 .

    1. JavaScript忽略了闰秒 .
  • 4
    var start= $("#firstDate").datepicker("getDate");
    var end= $("#SecondDate").datepicker("getDate");
    var days = (end- start) / (1000 * 60 * 60 * 24);
     alert(Math.round(days));
    

    jsfiddle示例:)

  • 5
    const startDate = '2017-11-08';
    const endDate   = '2017-10-01';
    const timeDiff  = (new Date(startDate)) - (new Date(endDate));
    const days      = timeDiff / (1000 * 60 * 60 * 24)
    
    • 设置开始日期

    • 设置结束日期

    • 计算差异

    • 将毫秒转换为天

  • 40

    获得两个日期之间差异的最简单方法:

    var diff =  Math.floor(( Date.parse(str2) - Date.parse(str1) ) / 86400000);
    

    您可以获得差异天数(如果无法解析其中一个或两个,则为NaN) . 解析日期以毫秒为单位给出结果,并且按天划分它需要将其除以24 * 60 * 60 * 1000

    如果你想要它除以天,小时,分钟,秒和毫秒:

    function dateDiff( str1, str2 ) {
        var diff = Date.parse( str2 ) - Date.parse( str1 ); 
        return isNaN( diff ) ? NaN : {
            diff : diff,
            ms : Math.floor( diff            % 1000 ),
            s  : Math.floor( diff /     1000 %   60 ),
            m  : Math.floor( diff /    60000 %   60 ),
            h  : Math.floor( diff /  3600000 %   24 ),
            d  : Math.floor( diff / 86400000        )
        };
    }
    

    这是我的重构版James版本:

    function mydiff(date1,date2,interval) {
        var second=1000, minute=second*60, hour=minute*60, day=hour*24, week=day*7;
        date1 = new Date(date1);
        date2 = new Date(date2);
        var timediff = date2 - date1;
        if (isNaN(timediff)) return NaN;
        switch (interval) {
            case "years": return date2.getFullYear() - date1.getFullYear();
            case "months": return (
                ( date2.getFullYear() * 12 + date2.getMonth() )
                -
                ( date1.getFullYear() * 12 + date1.getMonth() )
            );
            case "weeks"  : return Math.floor(timediff / week);
            case "days"   : return Math.floor(timediff / day); 
            case "hours"  : return Math.floor(timediff / hour); 
            case "minutes": return Math.floor(timediff / minute);
            case "seconds": return Math.floor(timediff / second);
            default: return undefined;
        }
    }
    
  • 184

    我建议使用moment.js库(http://momentjs.com/docs/#/displaying/difference/) . 它正确处理夏令时,一般来说都很适合 .

    例:

    var start = moment("2013-11-03");
    var end = moment("2013-11-04");
    end.diff(start, "days")
    1
    
  • 6

    我会继续grab this small utility并在其中为您找到这个功能 . 这是一个简短的例子:

    <script type="text/javascript" src="date.js"></script>
            <script type="text/javascript">
                var minutes = 1000*60;
                var hours = minutes*60;
                var days = hours*24;
    
                var foo_date1 = getDateFromFormat("02/10/2009", "M/d/y");
                var foo_date2 = getDateFromFormat("02/12/2009", "M/d/y");
    
                var diff_date = Math.round((foo_date2 - foo_date1)/days);
                alert("Diff date is: " + diff_date );
            </script>
    
  • 3

    使用Moment.js

    var future = moment('05/02/2015');
    var start = moment('04/23/2015');
    var d = future.diff(start, 'days'); // 9
    console.log(d);
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment-with-locales.min.js"></script>
    
  • 2

    JS中的日期值是日期时间值 .

    因此,直接日期计算不一致:

    (2013-11-05 00:00:00) - (2013-11-04 10:10:10) < 1 day
    

    例如,我们需要转换第二个日期:

    (2013-11-05 00:00:00) - (2013-11-04 00:00:00) = 1 day
    

    该方法可能会截断两个日期的工厂:

    var date1 = new Date('2013/11/04 00:00:00');
    var date2 = new Date('2013/11/04 10:10:10'); //less than 1
    var start = Math.floor(date1.getTime() / (3600 * 24 * 1000)); //days as integer from..
    var end = Math.floor(date2.getTime() / (3600 * 24 * 1000)); //days as integer from..
    var daysDiff = end - start; // exact dates
    console.log(daysDiff);
    
    date2 = new Date('2013/11/05 00:00:00'); //1
    
    var start = Math.floor(date1.getTime() / (3600 * 24 * 1000)); //days as integer from..
    var end = Math.floor(date2.getTime() / (3600 * 24 * 1000)); //days as integer from..
    var daysDiff = end - start; // exact dates
    console.log(daysDiff);
    
  • 7

    要计算2个给定日期之间的天数,您可以使用以下代码 . 我在这里使用的日期是2016年1月1日和2016年12月31日

    var day_start = new Date("Jan 01 2016");
    var day_end = new Date("Dec 31 2016");
    var total_days = (day_end - day_start) / (1000 * 60 * 60 * 24);
    document.getElementById("demo").innerHTML = Math.round(total_days);
    
    <h3>DAYS BETWEEN GIVEN DATES</h3>
    <p id="demo"></p>
    
  • 0

    最好通过使用UTC时间摆脱DST,Math.ceil,Math.floor等:

    var firstDate = Date.UTC(2015,01,2);
    var secondDate = Date.UTC(2015,04,22);
    var diff = Math.abs((firstDate.valueOf() 
        - secondDate.valueOf())/(24*60*60*1000));
    

    这个例子给出了差异109天 . 24*60*60*1000 是一天(以毫秒为单位) .

  • 6

    如何使用DatePicker小部件中的formatDate?您可以使用它来转换时间戳格式的日期(自1970年1月1日起的毫秒),然后进行简单的减法 .

  • 3

    当我想在两个日期做一些计算时,我发现了这个问题,但日期有小时和分钟值,我修改了@ michael-liu的答案以符合我的要求,并且它通过了我的测试 .

    差异天 2012-12-31 23:002013-01-01 01:00 应该等于1.(2小时)差异天 2012-12-31 01:002013-01-01 23:00 应该等于1.(46小时)

    function treatAsUTC(date) {
        var result = new Date(date);
        result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
        return result;
    }
    
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    function diffDays(startDate, endDate) {
        return Math.floor(treatAsUTC(endDate) / millisecondsPerDay) - Math.floor(treatAsUTC(startDate) / millisecondsPerDay);
    }
    
  • 9

    我认为解决方案不正确100%我会使用 ceil 而不是 floor ,round会工作,但这不是正确的操作 .

    function dateDiff(str1, str2){
        var diff = Date.parse(str2) - Date.parse(str1); 
        return isNaN(diff) ? NaN : {
            diff: diff,
            ms: Math.ceil(diff % 1000),
            s: Math.ceil(diff / 1000 % 60),
            m: Math.ceil(diff / 60000 % 60),
            h: Math.ceil(diff / 3600000 % 24),
            d: Math.ceil(diff / 86400000)
        };
    }
    
  • 105

    using milliseconds 时要小心 .

    date.getTime() 返回毫秒并执行 math operation with milliseconds requires to include

    • 夏令时(DST)

    • 检查两个日期是否具有相同的时间(小时,分钟,秒,毫秒)

    • 确保需要天差的行为:2016年9月19日 - 2016年9月29日= 1天或2天的差异?

    上面评论的例子是我到目前为止找到的最佳解决方案https://stackoverflow.com/a/11252167/2091095 . 但如果你想要计算所涉及的所有日子,请使用 +1 到它的结果 .

    function treatAsUTC(date) {
        var result = new Date(date);
        result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
        return result;
    }
    
    function daysBetween(startDate, endDate) {
        var millisecondsPerDay = 24 * 60 * 60 * 1000;
        return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
    }
    
    var diff = daysBetween($('#first').val(), $('#second').val()) + 1;
    
  • 3
    function timeDifference(date1, date2) {
      var oneDay = 24 * 60 * 60; // hours*minutes*seconds
      var oneHour = 60 * 60; // minutes*seconds
      var oneMinute = 60; // 60 seconds
      var firstDate = date1.getTime(); // convert to milliseconds
      var secondDate = date2.getTime(); // convert to milliseconds
      var seconds = Math.round(Math.abs(firstDate - secondDate) / 1000); //calculate the diffrence in seconds
      // the difference object
      var difference = {
        "days": 0,
        "hours": 0,
        "minutes": 0,
        "seconds": 0,
      }
      //calculate all the days and substract it from the total
      while (seconds >= oneDay) {
        difference.days++;
        seconds -= oneDay;
      }
      //calculate all the remaining hours then substract it from the total
      while (seconds >= oneHour) {
        difference.hours++;
        seconds -= oneHour;
      }
      //calculate all the remaining minutes then substract it from the total 
      while (seconds >= oneMinute) {
        difference.minutes++;
        seconds -= oneMinute;
      }
      //the remaining seconds :
      difference.seconds = seconds;
      //return the difference object
      return difference;
    }
    console.log(timeDifference(new Date(2017,0,1,0,0,0),new Date()));
    
  • 6
    Date.prototype.days = function(to) {
      return Math.abs(Math.floor(to.getTime() / (3600 * 24 * 1000)) - Math.floor(this.getTime() / (3600 * 24 * 1000)))
    }
    
    
    console.log(new Date('2014/05/20').days(new Date('2014/05/23'))); // 3 days
    
    console.log(new Date('2014/05/23').days(new Date('2014/05/20'))); // 3 days
    
  • 0

    这可能不是最优雅的解决方案,但我认为它似乎用相对简单的代码来回答这个问题 . 你不能使用这样的东西:

    function dayDiff(startdate, enddate) {
      var dayCount = 0;
    
      while(enddate >= startdate) {
        dayCount++;
        startdate.setDate(startdate.getDate() + 1);
      }
    
    return dayCount; 
    }
    

    这假设您将日期对象作为参数传递 .

  • 5

    我在Angular中遇到了同样的问题 . 我做副本,因为否则他将覆盖第一个日期 . 两个日期的时间必须为00:00:00(显然)

    /*
    * Deze functie gebruiken we om het aantal dagen te bereken van een booking.
    * */
    $scope.berekenDagen = function ()
    {
        $scope.booking.aantalDagen=0;
    
        /*De loper is gelijk aan de startdag van je reservatie.
         * De copy is nodig anders overschijft angular de booking.van.
         * */
        var loper = angular.copy($scope.booking.van);
    
        /*Zolang de reservatie beschikbaar is, doorloop de weekdagen van je start tot einddatum.*/
        while (loper < $scope.booking.tot) {
            /*Tel een dag op bij je loper.*/
            loper.setDate(loper.getDate() + 1);
            $scope.booking.aantalDagen++;
        }
    
        /*Start datum telt natuurlijk ook mee*/
        $scope.booking.aantalDagen++;
        $scope.infomsg +=" aantal dagen: "+$scope.booking.aantalDagen;
    };
    
  • 1

    如果你有两个unix时间戳,你可以使用这个函数(为了清晰起见,使其更加冗长):

    // Calculate number of days between two unix timestamps
    // ------------------------------------------------------------
    var daysBetween = function(timeStampA, timeStampB) {
        var oneDay = 24 * 60 * 60 * 1000; // hours * minutes * seconds * milliseconds
        var firstDate = new Date(timeStampA * 1000);
        var secondDate = new Date(timeStampB * 1000);
        var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
        return diffDays;
    };
    

    例:

    daysBetween(1096580303, 1308713220); // 2455
    
  • 3

    我使用下面的代码来试验新闻帖子的发布日期功能 . 我根据发布日期和当前日期计算分钟或小时或日或年 .

    var startDate= new Date("Mon Jan 01 2007 11:00:00");
    var endDate  =new Date("Tue Jan 02 2007 12:50:00");
    var timeStart = startDate.getTime();
    var timeEnd = endDate.getTime();
    var yearStart = startDate.getFullYear();
    var yearEnd   = endDate.getFullYear();
    if(yearStart == yearEnd)
     {
      var hourDiff = timeEnd - timeStart; 
      var secDiff = hourDiff / 1000;
      var minDiff = hourDiff / 60 / 1000; 
      var hDiff = hourDiff / 3600 / 1000; 
      var myObj = {};
      myObj.hours = Math.floor(hDiff);
      myObj.minutes = minDiff  
      if(myObj.hours >= 24)
       {
        console.log(Math.floor(myObj.hours/24) + "day(s) ago")
       } 
     else if(myObj.hours>0)
      {
       console.log(myObj.hours +"hour(s) ago")
      }
     else
      {
       console.log(Math.abs(myObj.minutes) +"minute(s) ago")
      }
    }
    else
    {
    var yearDiff = yearEnd - yearStart;
    console.log( yearDiff +" year(s) ago");
    }
    
  • 337

    如果你想要一个带日期的DateArray试试这个:

    <script>
            function getDates(startDate, stopDate) {
            var dateArray = new Array();
            var currentDate = moment(startDate);
            dateArray.push( moment(currentDate).format('L'));
    
            var stopDate = moment(stopDate);
            while (dateArray[dateArray.length -1] != stopDate._i) {
                dateArray.push( moment(currentDate).format('L'));
                currentDate = moment(currentDate).add(1, 'days');
            }
            return dateArray;
          }
    </script>
    

    DebugSnippet

  • 3

    计算两个日期之间的天数的简单方法是删除它们的两个时间分量,即将小时,分钟,秒和毫秒设置为0,然后减去它们的时间并以毫秒一天的 Value 潜水 .

    var firstDate= new Date(firstDate.setHours(0,0,0,0));
    var secondDate= new Date(secondDate.setHours(0,0,0,0));
    var timeDiff = firstDate.getTime() - secondDate.getTime();
    var diffDays =timeDiff / (1000 * 3600 * 24);
    
  • 12
    function formatDate(seconds, dictionary) {
        var foo = new Date;
        var unixtime_ms = foo.getTime();
        var unixtime = parseInt(unixtime_ms / 1000);
        var diff = unixtime - seconds;
        var display_date;
        if (diff <= 0) {
            display_date = dictionary.now;
        } else if (diff < 60) {
            if (diff == 1) {
                display_date = diff + ' ' + dictionary.second;
            } else {
                display_date = diff + ' ' + dictionary.seconds;
            }
        } else if (diff < 3540) {
            diff = Math.round(diff / 60);
            if (diff == 1) {
                display_date = diff + ' ' + dictionary.minute;
            } else {
                display_date = diff + ' ' + dictionary.minutes;
            }
        } else if (diff < 82800) {
            diff = Math.round(diff / 3600);
            if (diff == 1) {
                display_date = diff + ' ' + dictionary.hour;
            } else {
                display_date = diff + ' ' + dictionary.hours;
            }
        } else {
            diff = Math.round(diff / 86400);
            if (diff == 1) {
                display_date = diff + ' ' + dictionary.day;
            } else {
                display_date = diff + ' ' + dictionary.days;
            }
        }
        return display_date;
    }
    
  • 10

    一个更好的解决方案

    忽略时间部分

    如果两个日期相同,它将返回0 .

    function dayDiff(firstDate, secondDate) {
      firstDate = new Date(firstDate);
      secondDate = new Date(secondDate);
      if (!isNaN(firstDate) && !isNaN(secondDate)) {
        firstDate.setHours(0, 0, 0, 0); //ignore time part
        secondDate.setHours(0, 0, 0, 0); //ignore time part
        var dayDiff = secondDate - firstDate;
        dayDiff = dayDiff / 86400000; // divide by milisec in one day
        console.log(dayDiff);
      } else {
        console.log("Enter valid date.");
      }
    }
    
    $(document).ready(function() {
      $('input[type=datetime]').datepicker({
        dateFormat: "mm/dd/yy",
        changeMonth: true,
        changeYear: true
      });
      $("#button").click(function() {
        dayDiff($('#first').val(), $('#second').val());
      });
    });
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    
    <input type="datetime" id="first" value="12/28/2016" />
    <input type="datetime" id="second" value="12/28/2017" />
    <input type="button" id="button" value="Calculate">
    
  • 4
    function validateDate() {
            // get dates from input fields
            var startDate = $("#startDate").val();
            var endDate = $("#endDate").val();
            var sdate = startDate.split("-");
            var edate = endDate.split("-");
            var diffd = (edate[2] - sdate[2]) + 1;
            var leap = [ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
            var nonleap = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
            if (sdate[0] > edate[0]) {
                alert("Please enter End Date Year greater than Start Date Year");
                document.getElementById("endDate").value = "";
                diffd = "";
            } else if (sdate[1] > edate[1]) {
                alert("Please enter End Date month greater than Start Date month");
                document.getElementById("endDate").value = "";
                diffd = "";
            } else if (sdate[2] > edate[2]) {
                alert("Please enter End Date greater than Start Date");
                document.getElementById("endDate").value = "";
                diffd = "";
            } else {
                if (sdate[0] / 4 == 0) {
                    while (sdate[1] < edate[1]) {
                        diffd = diffd + leap[sdate[1]++];
                    }
                } else {
                    while (sdate[1] < edate[1]) {
                        diffd = diffd + nonleap[sdate[1]++];
                    }
                }
                document.getElementById("numberOfDays").value = diffd;
            }
        }
    
  • 0

    您可以使用UnderscoreJS进行格式化和计算差异 .

    Demo https://jsfiddle.net/sumitridhal/8sv94msp/

    var startDate = moment("2016-08-29T23:35:01");
    var endDate = moment("2016-08-30T23:35:01");  
      
    
    console.log(startDate);
    console.log(endDate);
    
    var resultHours = endDate.diff(startDate, 'hours', true);
    
    document.body.innerHTML = "";
    document.body.appendChild(document.createTextNode(resultHours));
    
    body { white-space: pre; font-family: monospace; }
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
    
  • 77

    Bookmarklet版本的其他答案,提示您两个日期:

    javascript:(function() {
        var d = new Date(prompt("First Date or leave blank for today?") || Date.now());
        prompt("Days Between", Math.round(
            Math.abs(
                (d.getTime() - new Date(prompt("Date 2")).getTime())
                    /(24*60*60*1000)
                 )
            ));
    })();
    
  • 3

    我只有两个时间戳以毫秒为单位,所以我必须用moment.js做一些额外的步骤以获得它们之间的日子 .

    const getDaysDiff = (fromTimestamp, toTimestamp) => {
        // set timezone offset with utcOffset if needed
        let fromDate = moment(fromTimestamp).utcOffset(8);
        let toDate = moment(toTimestamp).utcOffset(8);
        // get the start moment of the day
        fromDate.set({'hour':0, 'minute': 0, 'second': 0, 'millisecond': 0});
        toDate.set({'hour':0, 'minute': 0, 'second': 0, 'millisecond': 0});
        let diffDays = toDate.diff(fromDate, 'days');
    
        return diffDays;
    }
    
    getDaysDiff(1528889400000, 1528944180000)// 1
    

相关问题