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

<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中获得两个日期之间的天数?


当前回答

使用毫秒时要小心。

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;

其他回答

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

虽然数学。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 UTC, 3/11/2013太平洋夏令时12:00 AM (UTC-07:00)存储为3/11/2013上午7:00 UTC。在这一天,从午夜到午夜,当地时间在UTC只有23小时!

虽然本地时间中的一天可以大于或小于24小时,但国际标准时间中的一天总是24小时上面所示的daysBetween方法利用了这一事实,它首先调用treatAsUTC将本地时间调整为午夜UTC,然后再进行减法和除法。

1. JavaScript忽略闰秒。

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

我只有两个以毫秒为单位的时间戳,所以我必须用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 

区分两个日期的最简单方法是:

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