如何计算两个日期之间的天数?

How to calculate number of days between two dates?

提问人:Michael Haren 提问时间:2/13/2009 最后编辑:TheMasterMichael Haren 更新时间:11/17/2023 访问量:767937

问:

例如,在输入框中给定两个日期:

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

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

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

JavaScript 日期

评论

20赞 Mihail Shishkov 5/25/2017
在99%的用户要求“两个日期之间的天数”的情况下,她不明白的是,她试图将苹果与梨进行比较。如果被问到“一个日期范围内有多少个日期?”,或者我必须在日历上划过多少个方格,问题就会变得如此简单。这留下了时间和夏令时问题等。由于日期时间数据结构纯粹是无稽之谈,因此我们隐含了混淆。没有日期时间这样的东西,有日期和时间,这是两个在性质和行为上截然不同的对象
0赞 Edward 11/1/2018
对于将差分成(整个)时间单位的函数,请使用 stackoverflow.com/a/53092438/3787376 处的答案。
1赞 RobG 3/17/2019
我觉得这个问题应该被删除或至少标记为“避免”,因为大多数答案要么不正确,要么依赖于各种库。
0赞 MC Emperor 12/12/2020
如果 JavaScript 没有提供正确的内置方法,@RobG库是唯一的选择。
3赞 RobG 12/12/2020
@MCEmperor - 几乎没有,得票最高的答案只有 3 行代码,其中两行用于解析。

答:

4赞 kgiannakakis 2/13/2009 #1

使用 DatePicker 小部件中的 formatDate 怎么样?您可以使用它以时间戳格式转换日期(自 01/01/1970 以来的毫秒),然后进行简单的减法。

535赞 Miles 2/13/2009 #2

这是一个快速而肮脏的实现,作为解决问题中提出的问题的概念证明。它依赖于这样一个事实,即您可以通过减去两个日期来获得它们之间经过的毫秒数,从而将它们强制转换为其原始数字值(自 1970 年初以来的毫秒数)。datediff

/**
 * Take the difference between the dates and divide by milliseconds per day.
 * Round to nearest whole number to deal with DST.
 */
function datediff(first, second) {        
    return Math.round((second - first) / (1000 * 60 * 60 * 24));
}

/**
 * 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]);
}

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 框架。

评论

3赞 Jin Wang 7/7/2016
我认为Math.trunc()更合适。以防万一有人使用更精确的 Date 对象(即包括小时、分钟和秒)
40赞 osullic 9/21/2016
作为标记为正确且票数最高的答案(截至目前),值得评论的是,此答案没有正确处理夏令时。请看Michael Liu的回答。
2赞 RobG 2/17/2017
@osullic - 此答案使用 Math.round 处理夏令时,但它确实希望仅提供日期字符串,而不是日期和时间。
3赞 ViqMontana 5/18/2017
请记住,在此示例中,日期采用美国格式,即 MM/DD/YYYY。如果您需要英国版本,则需要将方法更改为:parseDatereturn new Date(mdy[2], mdy[1], mdy[0]-1);
1赞 ICW 3/10/2022
仅用于解析日期。您的函数正常工作的任何情况,都将在所有浏览器中正常工作new DateparseDatenew Date
44赞 fuentesjr 2/13/2009 #3

我会继续抓住这个小实用程序,您将在其中找到适合您的功能。下面是一个简短的示例:

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

评论

0赞 Cameron Buck 4/13/2022
为该实用程序提供的链接已失效。
140赞 some 2/13/2009 #4

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

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

评论

10赞 Phil B 8/29/2018
糟糕的答案。Math.floor() 在夏令时中,当时钟向前移动时,您将失去一天。在大多数情况下,Math.round() 会给出正确的答案,但在其他答案中也有更好的选择。
0赞 stomy 12/2/2020
@some 你在哪里看到詹姆斯版本?詹姆斯是谁?
0赞 some 1/5/2021
@stomy 看起来那个版本被删除了——
0赞 Penny Liu 9/1/2021
使用可能满足您的需求。Math.abs
6赞 Tolo Palmer 3/15/2012 #5

我会使用 ceil 而不是地板,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)
    };
}

评论

5赞 Rich Dougherty 4/8/2012
天可以超过 24 小时,分钟可以超过 60 秒。在这些情况下,使用 Math.ceil() 会过度计数。
266赞 Michael Liu 6/29/2012 #6

在撰写本文时,只有其他答案之一正确处理 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

虽然返回了正确的结果,但我认为它有点笨拙。相反,通过显式考虑 DST 开始或结束时对 UTC 偏移量的更改,我们可以使用精确的算术:Math.round

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 日期计算很棘手,因为对象在内部以 UTC 而不是本地时间存储时间。例如,2013 年 3 月 10 日太平洋标准时间 (UTC-08:00) 上午 12:00 存储为 2013 年 3 月 10 日上午 8:00 UTC,2013 年 3 月 11 日太平洋夏令时间 12:00 上午 (UTC-07:00) 存储为 2013 年 3 月 11 日上午 7:00 UTC。在这一天,当地时间午夜到午夜只有 UTC 的 23 小时!Date

虽然本地时间的一天可以多于或少于 24 小时,但 UTC 中的一天始终正好是 24 小时。1 上面显示的方法利用了这一事实,首先调用将两个本地时间调整为午夜 UTC,然后再进行减法和除法。daysBetweentreatAsUTC

1. JavaScript 忽略闰秒。

评论

3赞 RobG 2/17/2017
无需使用 UTC,只需将本地时间设置为午夜(或两个日期的值相同)即可。夏令时引入的小数天最多只有 0.04 ±(在某些地方甚至更少),因此它以 Math.round 结束。;-)依靠 Date 构造函数来分析字符串不是一个好主意。如果您确实想使用 UTC 值,请首先解析字符串。Date.UTC(...)
3赞 Michael Liu 2/17/2017
@RobG:正如我在回答中所说:“虽然 Math.round 返回了正确的结果,但我认为它有点笨拙。相反,通过显式考虑 DST 开始或结束时 UTC 偏移量的变化,我们可以使用精确的算术。
2赞 JDB 8/15/2019
实际上,从技术上讲,您表示为“不正确”的时间是正确的。您没有将 DateTimes 更改为 UTC...您只需更改每个 DateTime 的时间即可获得人工整数。四舍五入并不“笨拙”......这是完全正确的方法,因为无论如何,这就是你在脑海中做的事情:你正在四舍五入时间部分(小时、分钟、秒),只是试图得到一整天的数字。
8赞 guilin 桂林 3/27/2013 #7

当我想在两个日期进行一些计算时,我发现了这个问题,但是日期有小时和分钟值,我修改了@michael-liu的答案以满足我的要求,它通过了我的测试。

diff 天数,应等于 1。(2小时) diff 天数,应等于 1。(46小时)2012-12-31 23:002013-01-01 01:002012-12-31 01:002013-01-01 23:00

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);
}
132赞 stephenbez 8/22/2013 #8

我建议使用 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

评论

30赞 Jason Axelson 12/3/2016
作为一个警告,虽然momentjs很棒,但它是一个相当大的依赖
11赞 Norris 11/20/2013 #9

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

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

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

例如,我们需要转换 de 2nd date:

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

5赞 Abdennour TOUMI 12/2/2014 #10

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

7赞 Popmatic 4/3/2015 #11

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

function dayDiff(startdate, enddate) {
  var dayCount = 0;

  while(enddate >= startdate) {
    dayCount++;
    startdate.setDate(startdate.getDate() + 1);
  }

return dayCount; 
}

这是假设您正在将日期对象作为参数传递。

10赞 Timo Kähkönen 4/30/2015 #12

最好使用 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

评论

0赞 Lev Lukomskyi 3/30/2021
值得补充的是,如果您想要 UTC 中的当前日期,您可以这样做:var now = new Date(); var utcNow = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())
17赞 Michael K 5/1/2015 #13

使用 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>

评论

1赞 Sharif 7/13/2017
moment.js对于诸如 YTD diff counts more 之类的事情非常方便:momentjs.comvar now = moment(), yearStart = moment().startOf('year'); var ytdDays = now.diff(yearStart, 'days'); // this can be years, months, weeks, days, hours, minutes, and seconds console.log(ytdDays);
4赞 user3806549 7/2/2015 #14

我在 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赞 Parmanand Shete 12/3/2015 #15
   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;
        }
    }
4赞 Wallace Sidhrée 12/17/2015 #16

如果你有两个 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
12赞 NooNa MarJa 1/11/2016 #17

要计算 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>

9赞 riv 7/14/2016 #18

可以使用以下公式计算不同 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);

3赞 Ramees Rahath 7/21/2016 #19

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

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

评论

0赞 Marco Scabbiolo 7/21/2016
请解释您的代码,并且您解决了问题,只是粘贴代码被认为是一个错误的答案。
2赞 Michael Parker 7/22/2016
虽然此代码可以回答问题,但提供有关它如何和/或为什么解决问题的其他上下文将提高答案的长期价值。
0赞 Ramees Rahath 7/23/2016
感谢 @MarcoScabbiolo,@Michael Parker 的评论。由于我在回答方面是 Stackoverflow 的新手,我不知道应该如何提供解决方案
3赞 Ricardo Fercher 9/7/2016 #20

如果你想有一个带有日期的 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>

调试代码段

4赞 Dalibor Matura 9/20/2016 #21

使用毫秒时要小心。

date.getTime() 返回毫秒,用毫秒进行数学运算需要包括

  • 夏令时 (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;
7赞 Aravindh Gopi 11/21/2016 #22
var start= $("#firstDate").datepicker("getDate");
var end= $("#SecondDate").datepicker("getDate");
var days = (end- start) / (1000 * 60 * 60 * 24);
 alert(Math.round(days));

jsfiddle 示例 :)

5赞 Noreddine Belhadj Cheikh 1/22/2017 #23

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

评论

1赞 RBT 1/22/2017
请允许我请求您围绕您的回答添加更多背景信息。只有代码的答案很难理解。如果您可以在帖子中添加更多信息,这将对提问者和未来的读者有所帮助。
2赞 Mihail Shishkov 5/25/2017
@N.Belhadj,你可以用简单的div和mod(%)操作替换所有这些while循环
2赞 zloctb 2/18/2017 #24
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;
}
0赞 Sumit Ridhal 5/4/2017 #25

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

演示 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>

-1赞 drzaus 7/26/2017 #26

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

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)
             )
        ));
})();
4赞 Sriman Pathy 9/19/2017 #27

计算两个日期之间的天数的简单方法是删除它们的两个时间部分,即将小时、分钟、秒和毫秒设置为 0,然后减去它们的时间,然后将其转换为一天的毫秒。

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

评论

0赞 AaA 2/24/2020
您的解决方案的问题是,您假设 firstDate 和 secondDate 是日期,然后无需再次将它们更改为日期,如果它们不是日期*不是),您将在 setHours 上收到错误。要更正此问题,您需要将 setHours 移出new Date
3赞 Sumit Joshi 9/28/2017 #28

更好的解决方案

忽略时间部分

如果两个日期相同,它将返回 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">

评论

0赞 Sachin Pakale 12/18/2023
这是完美的。通过忽略时间,您可以获得实际的日差。
-1赞 Edward 10/2/2017 #29

这个答案基于另一个答案(末尾的链接),是关于两个日期之间的差异。
你可以看到它是如何工作的,因为它很简单,它还包括将差异拆分为
时间单位(我做的一个函数)并转换为 UTC 以停止时区问题。

function date_units_diff(a, b, unit_amounts) {
    var split_to_whole_units = function (milliseconds, unit_amounts) {
        // unit_amounts = list/array of amounts of milliseconds in a
        // second, seconds in a minute, etc., for example "[1000, 60]".
        time_data = [milliseconds];
        for (i = 0; i < unit_amounts.length; i++) {
            time_data.push(parseInt(time_data[i] / unit_amounts[i]));
            time_data[i] = time_data[i] % unit_amounts[i];
        }; return time_data.reverse();
    }; if (unit_amounts == undefined) {
        unit_amounts = [1000, 60, 60, 24];
    };
    var utc_a = new Date(a.toUTCString());
    var utc_b = new Date(b.toUTCString());
    var diff = (utc_b - utc_a);
    return split_to_whole_units(diff, unit_amounts);
}

// Example of use:
var d = date_units_diff(new Date(2010, 0, 1, 0, 0, 0, 0), new Date()).slice(0,-2);
document.write("In difference: 0 days, 1 hours, 2 minutes.".replace(
   /0|1|2/g, function (x) {return String( d[Number(x)] );} ));

上面的代码是如何工作的

可以使用 Date 对象计算日期/时间差(以毫秒为单位):

var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.

var utc_a = new Date(a.toUTCString());
var utc_b = new Date(b.toUTCString());
var diff = (utc_b - utc_a); // The difference as milliseconds.

然后,要计算出该差值中的秒数,请将其除以 1000 以将毫秒转换为秒,然后将
结果更改为整数(整数)以删除
毫秒(该小数点的小数部分):。
此外,我可以使用相同的过程获得更长的时间单位,例如:
-(整)分钟将秒除以 60 并将结果更改为整数,
- 小时,将分钟除以 60 并将结果更改为整数。
var seconds = parseInt(diff/1000)

我创建了一个函数,用于执行将差分成
整个时间单位的过程,名为 ,并演示:
split_to_whole_units

console.log(split_to_whole_units(72000, [1000, 60]));
// -> [1,12,0] # 1 (whole) minute, 12 seconds, 0 milliseconds.

这个答案是基于另一个答案。

124赞 marcobiedermann 11/8/2017 #30

以下解决方案将假定这些变量在代码中可用:

const startDate  = '2020-01-01';
const endDate    = '2020-03-15';

原生 JS

步骤:

  1. 设置开始日期
  2. 设置结束日期
  3. 计算差值
  4. 将毫秒转换为天
const diffInMs   = new Date(endDate) - new Date(startDate)
const diffInDays = diffInMs / (1000 * 60 * 60 * 24);

评论:

我知道这不是您问题的一部分,但总的来说,我不建议在普通 JavaScript 中进行任何日期计算或操作,而是使用像 date-fnsLuxonmoment.js 这样的库,因为有许多边缘情况。

这个普通的 JavaScript 答案将天数计算为十进制数。此外,在使用夏令时,它可能会遇到极端情况


使用库

- 日期-fns

const differenceInDays = require('date-fns/differenceInDays');
const diffInDays = differenceInDays(new Date(endDate), new Date(startDate));

文档:https://date-fns.org/v2.16.1/docs/differenceInDays

- 卢克森

const { DateTime } = require('luxon');
const diffInDays = DateTime.fromISO(endDate).diff(DateTime.fromISO(startDate), 'days').toObject().days;

文档:https://moment.github.io/luxon/api-docs/index.html#datetimediff

- 时刻.js

const moment = require('moment');
const diffInDays = moment(endDate).diff(moment(startDate), 'days');

文档:https://momentjs.com/docs/#/displaying/difference/


RunKit 上的示例

评论

9赞 daCoda 1/24/2019
我很欣赏这样的答案:简短、简单且不需要随机依赖!干杯。
2赞 Feyisayo Sonubi 8/4/2019
是不是只有我才以负数回报?不应该是 ?timeDifftimeDiff(new Date(endDate)) - (new Date(startDate));
0赞 marcobiedermann 8/4/2019
@feyisayo-sonubi 取决于您传入开始和结束日期的顺序。在此示例中(new Date('2017-11-08')) - (new Date('2017-10-01')) // 3283200000
0赞 Ben Racicot 4/19/2020
const timeDiff = +(new Date(start)) - +(new Date(end));
0赞 dcromley 5/21/2020
伟大。虽然我更喜欢return (Date.UTC(yr2, mo2-1, dy2) - Date.UTC(yr1, mo1-1, dy1)) / 86400000;
-1赞 wj2061 6/12/2018 #31

我在毫秒内只得到了两个时间戳,所以我必须使用 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 
-1赞 Adelson Silva Couto 9/9/2018 #32

1970-01-01 之前和 2038-01-19 之后的贡献

function DateDiff(aDate1, aDate2) {
  let dDay = 0;
  this.isBissexto = (aYear) => {
    return (aYear % 4 == 0 && aYear % 100 != 0) || (aYear % 400 == 0);
  };
  this.getDayOfYear = (aDate) => {
    let count = 0;
    for (let m = 0; m < aDate.getUTCMonth(); m++) {
      count += m == 1 ? this.isBissexto(aDate.getUTCFullYear()) ? 29 : 28 : /(3|5|8|10)/.test(m) ? 30 : 31;
    }
    count += aDate.getUTCDate();
    return count;
  };
  this.toDays = () => {
    return dDay;
  };
  (() => {
    let startDate = aDate1.getTime() <= aDate2.getTime() ? new Date(aDate1.toISOString()) : new Date(aDate2.toISOString());
    let endDate = aDate1.getTime() <= aDate2.getTime() ? new Date(aDate2.toISOString()) : new Date(aDate1.toISOString());
    while (startDate.getUTCFullYear() != endDate.getUTCFullYear()) {
      dDay += (this.isBissexto(startDate.getFullYear())? 366 : 365) - this.getDayOfYear(startDate) + 1;
      startDate = new Date(startDate.getUTCFullYear()+1, 0, 1);
    }
    dDay += this.getDayOfYear(endDate) - this.getDayOfYear(startDate);
  })();
}
1赞 Lewis Nakao 1/23/2019 #33

我从其他答案中汲取了一些灵感,并使输入具有自动卫生功能。我希望这能很好地改进其他答案。

我还建议使用有助于验证用户输入的字段。<input type="date">

//use best practices by labeling your constants.
let MS_PER_SEC = 1000
  , SEC_PER_HR = 60 * 60
  , HR_PER_DAY = 24
  , MS_PER_DAY = MS_PER_SEC * SEC_PER_HR * HR_PER_DAY
;

//let's assume we get Date objects as arguments, otherwise return 0.
function dateDiffInDays(date1Time, date2Time) {
    if (!date1Time || !date2Time) return 0;
    return Math.round((date2Time - date1Time) / MS_PER_DAY);
}

function getUTCTime(dateStr) {
  const date = new Date(dateStr);
  // If use 'Date.getTime()' it doesn't compute the right amount of days
  // if there is a 'day saving time' change between dates
  return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate());
}


function calcInputs() {
  let date1 = document.getElementById("date1")
    , date2 = document.getElementById("date2")
    , resultSpan = document.getElementById("result")
  ;
  if (date1.value && date2.value && resultSpan) {
    //remove non-date characters
    console.log(getUTCTime(date1.value));
    let date1Time = getUTCTime(date1.value)
      , date2Time = getUTCTime(date2.value)
      , result = dateDiffInDays(date1Time, date2Time)
    ;
    resultSpan.innerHTML = result + " days";
  }
}
window.onload = function() { calcInputs(); };

//some code examples
console.log(dateDiffInDays(new Date("1/15/2019"), new Date("1/30/2019")));
console.log(dateDiffInDays(new Date("1/15/2019"), new Date("2/30/2019")));
console.log(dateDiffInDays(new Date("1/15/2000"), new Date("1/15/2019")));
<input type="date" id="date1" value="2000-01-01" onchange="calcInputs();" />
<input type="date" id="date2" value="2022-01-01" onchange="calcInputs();"/>
Result: <span id="result"></span>

评论

2赞 Chesare 3/17/2021
我没有使用'date1.getTime()'和'date2.getTime()',而是使用'Date.UTC'来防止不属于同一天的日期之间的差异,从而节省时间(即2021年3月10日和2021年3月16日),以下函数可能会有所帮助:function getUTCTime(date) { // If use 'Date.getTime()' it doesn't compute the right amount of days // if there is a 'day saving time' change between dates return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()); }
3赞 OhhhThatVarun 1/26/2019 #34

简单、易用、精致。此函数将每 1 秒调用一次以更新时间。

const year = (new Date().getFullYear());
const bdayDate = new Date("04,11,2019").getTime(); //mmddyyyy

// countdown
let timer = setInterval(function () {

    // get today's date
    const today = new Date().getTime();

    // get the difference
    const diff = bdayDate - today;

    // math
    let days = Math.floor(diff / (1000 * 60 * 60 * 24));
    let hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    let minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
    let seconds = Math.floor((diff % (1000 * 60)) / 1000);

}, 1000);
0赞 Umang Loriya 11/28/2019 #35

在这种情况下,使用 moment 会容易得多,您可以尝试以下操作:

    let days = moment(yourFirstDateString).diff(moment(yourSecondDateString), 'days');

它会给你像 1、2、5、0 等这样的整数值,这样你就可以很容易地使用条件检查,比如:

if(days < 1) {

此外,还有一件事是您可以获得更准确的时间差结果(以小数形式表示,如 1.2、1.5、0.7 等)要获得这种结果,请使用以下语法:

let days = moment(yourFirstDateString).diff(moment(yourSecondDateString), 'days', true);

如果您有任何进一步的疑问,请告诉我

-2赞 Mamunur Rashid #36

如果我们想计算我们的年龄,这是一个有点不同的答案

    {
      birthday: 'April 22, 1993',
      names: {
        first: 'Keith',
        last: 'Buckley'
      }
    },
    {
      birthday: 'January 3, 1975',
      names: {
        first: 'Larry',
        last: 'Heep'
      }
    },
    {
      birthday: 'February 12, 1944',
      names: {
        first: 'Linda',
        last: 'Bermeer'
      }
    }
  ];
const cleanPeople = people.map(function ({birthday, names:{first, last}}) {
      // birthday, age, fullName;
      const now = new Date();
      var age =  Math.floor(( Date.parse(now) - Date.parse(birthday)) / 31536000000);
      return {
        age,
        fullName:`${first} ${last}`
      }
    });
    console.log(cleanPeople);
    console.table(cleanPeople);
7赞 nkitku 12/10/2020 #37

单衬垫和小型

const diff=(e,t)=>Math.floor((new Date(e).getTime()-new Date(t).getTime())/1000*60*60*24);

// or

const diff=(e,t)=>Math.floor((new Date(e)-new Date(t))/864e5);

// or

const diff=(a,b)=>(new Date(a)-new Date(b))/864e5|0; 

// use
diff('1/1/2001', '1/1/2000')

对于 TypeScript

const diff = (from: string, to: string) => Math.floor((new Date(from).getTime() - new Date(to).getTime()) / 86400000);
2赞 MC Emperor 12/12/2020 #38

我最近遇到了同样的问题,来自Java世界,我立即开始搜索JavaScript的JSR 310实现。JSR 310 是 Java 的日期和时间 API(自 Java 8 起提供的标准)。我认为 API 设计得很好。

幸运的是,有一个直接移植到 Javascript 的端口,称为 js-joda

首先,在:<head>

<script
    src="https://cdnjs.cloudflare.com/ajax/libs/js-joda/1.11.0/js-joda.min.js"
    integrity="sha512-piLlO+P2f15QHjUv0DEXBd4HvkL03Orhi30Ur5n1E4Gk2LE4BxiBAP/AD+dxhxpW66DiMY2wZqQWHAuS53RFDg=="
    crossorigin="anonymous"></script>

然后简单地这样做:

let date1 = JSJoda.LocalDate.of(2020, 12, 1);
let date2 = JSJoda.LocalDate.of(2021, 1, 1);
let daysBetween = JSJoda.ChronoUnit.DAYS.between(date1, date2);

现在包含两者之间的天数。请注意,结束日期是排他性的。daysBetween

12赞 borma425 4/29/2021 #39

试试这个

let today = new Date().toISOString().slice(0, 10)

const startDate  = '2021-04-15';
const endDate    = today;

const diffInMs   = new Date(endDate) - new Date(startDate)
const diffInDays = diffInMs / (1000 * 60 * 60 * 24);


alert( diffInDays  );

评论

0赞 vsync 6/19/2023
与更旧的答案相同
2赞 Ajay Prajapati 9/19/2022 #40
 // JavaScript / NodeJs answer  
   let startDate = new Date("2022-09-19");
   let endDate = new Date("2022-09-26");

   let difference = startDate.getTime() - endDate.getTime();
   
    console.log(difference);

   let TotalDiffDays = Math.ceil(difference / (1000 * 3600 * 24));
   console.log(TotalDiffDays + " days :) ");
0赞 trincot 11/17/2022 #41

夏令时问题使这里的许多答案无效。我将使用辅助函数来获取给定日期的唯一日期编号 -- 通过使用以下方法:UTC

const dayNumber = a => Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()) / (24*60*60*1000);
const daysBetween = (a, b) => dayNumber(b) - dayNumber(a);

// Testing it
const start = new Date(1000, 0, 1); // 1 January 1000
const end   = new Date(3000, 0, 1); // 1 January 3000
let current = new Date(start);
for (let days = 0; current < end; days++) {
    const diff = daysBetween(start, current);
    if (diff !== days) throw "test failed";
    current.setDate(current.getDate() + 1); // move current date one day forward
}
console.log("tests succeeded");

1赞 bookworm 8/24/2023 #42

最简单的答案,考虑到一天中的时间和闰年,可以归结为五行代码。如果知道您的条目永远不会有时间组件,则只需要三行代码。

  date1 = new Date("1/1/2000");
  date2 = new Date("1/1/2001");
  date1.setHours(0, 0, 0, 0); // this line accounts for date strings that have time components
  date2.setHours(0, 0, 0, 0); // this too
  daysBetween = Math.round((date2 - date1) / (24 * 60 * 60 * 1000));

我包含了一个名为 daysDiff 的完整记录函数,该函数接受 JavaScript 日期对象,如果参数格式不正确,则会引发错误。

/**
 * Calculate the number of days between two dates, taking into account possible leap years.
 * Returns a positive or negative integer.
 *
 * @param {Date} date1 - The earlier of the two dates.
 * @param {Date} date2 - The later of the two dates.
 * @throws {TypeError} - If either dateOne or dateTwo is not a valid Date object.
 * @returns {number}   - Integer number of days between date1 and date2.
*/
function daysDiff(date1, date2) {
  // Ensure date1 and date2 are valid Date objects
  if (!(date1 instanceof Date) || !(date2 instanceof Date)) {
      throw new TypeError('Both date1 and date2 must be valid Date objects.');
  }

  const millisecondsPerDay = 24 * 60 * 60 * 1000;
  
  // Reset time components to midnight to consistent days between without worrying about times.
  date1.setHours(0, 0, 0, 0);
  date2.setHours(0, 0, 0, 0);
  
  // Calculate the difference in milliseconds and convert to days
  return Math.round((date2 - date1) / millisecondsPerDay);
}

// accounts for leap year
console.log(daysDiff(new Date("1/1/2024"), new Date("4/30/2024")));

// returns the number of days between today and Jan 1, 2023
console.log(daysDiff(new Date("1/1/2023"), new Date()));

// returns a negative number as date1 is bigger than date2
console.log(daysDiff(new Date("1/30/2024"), new Date("1/1/2024")));

// ignores the time component so will return same result any time of day
console.log(daysDiff(new Date("1/30/2024 13:40:00", new Date())));

// throws an error because date1, while true, isn't a date.`
console.log(daysDiff("frogs are great", new Date()));

评论

0赞 miken32 8/24/2023
“从一个日期中减去另一个日期”与此处的其他 2 页答案(包括近 15 年前接受的答案)有何不同?
0赞 bookworm 8/24/2023
@miken32 我的回答比较笼统。公认的答案没有提供简单的方法来容纳像今天的日期 Date() 这样简单的东西。时间部分将导致不一致的结果。最接近我的答案来自 Sumit Joshi,我第一次通过这个错过了两个赞成票。他和我的唯一区别是我的有更好的记录。如果它太多余,我会拉我的。
0赞 Andy 11/17/2023 #43

房间里的大象是没有一个正确的答案!

如果您只想要 24 个日期之间的 24 小时周期数,那么只需减去它们,除以 86400000,根据您的个人要求向上或向下舍入,您就完成了。

如果你想要日历天数,这取决于你所在的时区:假设现在是晚上 11 点,你在曼谷,2 小时后对你来说将是不同的一天,但对于洛杉矶的人来说,这将是同一天。

只有当您确定 (a) 您正在比较的两个日期 (b) JavaScript 实例的时区 (c) 想知道答案的人都在同一时区时,您才能使用当地时间进行计算。

在所有其他情况下,您需要更仔细地考虑要实现的目标。例如,如果其中一个输入日期在曼谷,另一个在洛杉矶,那么即使两个输入值相同,天数差异仍可能为 1。

就我而言,我不知道两者的时区或输入日期或读取输出的人,因此我决定计算 UTC 中的日历天数,如下所示:

(
    Date.UTC(d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate()) 
    -
    Date.UTC(d2.getUTCFullYear(), d2.getUTCMonth(), d2.getUTCDate())
) / 86400000