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

Mic*_*ren 383 javascript date

如何获取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>
Run Code Online (Sandbox Code Playgroud)

Mil*_*les 390

这是一个快速而肮脏的实现datediff,作为解决问题中提出的问题的概念证明.它依赖于这样一个事实:你可以通过减去它们来获得两个日期之间经过的毫秒数,这会将它们强制转换为它们的原始数值(自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)));
Run Code Online (Sandbox Code Playgroud)
<input id="first" value="1/1/2000"/>
<input id="second" value="1/1/2001"/>
Run Code Online (Sandbox Code Playgroud)

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

此外,为了便于说明,该代码段使用window对象的命名访问权限,但在生产中,您应该使用标准化的API,如getElementById,或者更可能使用某些UI框架.

  • 作为标记正确和最高投票的答案(截至目前),值得评论的是,此答​​案无法正确处理夏令时.请参阅Michael Liu的回答. (20认同)
  • 请记住,在此示例中日期采用美国格式,即 MM/DD/YYYY。如果你需要英国版本,那么你需要将`parseDate`方法改为:`return new Date(mdy[2], mdy[1], mdy[0]-1);` (3认同)
  • 我认为Math.trunc()更合适。以防万一有人使用更精确的Date对象(例如,包括小时,分钟和秒) (2认同)
  • @osullic——这个答案使用 *Math.round* 处理夏令时,但是它确实希望只传递日期字符串,而不是日期和时间。 (2认同)
  • 只需使用“new Date”来解析日期。在“parseDate”函数正常工作的任何情况下,使用“new Date”都可以在所有浏览器中正常工作 (2认同)

Mic*_*Liu 197

在撰写本文时,只有其中一个答案正确处理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
Run Code Online (Sandbox Code Playgroud)

虽然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()));
Run Code Online (Sandbox Code Playgroud)

说明

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小时.1daysBetween上面显示的方法利用了这一事实,首先要求treatAsUTC在减去和分割之前调整本地时间到午夜UTC.

1. JavaScript忽略了闰秒.

  • 无需使用 UTC,只需将本地时间设置为午夜(或两个日期的相同值)即可。夏令时引入的小数天最多只有 ±0.04(在某些地方更少),因此它以 *Math.round* 结束。;-) 依靠 Date 构造函数来解析字符串不是一个好主意。如果你真的想使用 UTC 值,首先使用 `Date.UTC(...)` 解析字符串。 (2认同)
  • @RobG:正如我在答案中所述:"虽然Math.round返回正确的结果,但我认为它有些笨拙.相反,通过明确说明DST开始或结束时UTC偏移的变化,我们可以使用精确算术." (2认同)
  • 实际上,从技术上讲,您所表示的“不正确”时间是正确的。您没有将 DateTimes 更改为 UTC...您只是更改每个 DateTime 的时间以获得一个人工整数。四舍五入并不“笨重”......这正是正确的方法,因为无论如何这就是你在头脑中所做的事情:你四舍五入时间部分(小时,分钟,秒),只是想得到一个整数天数。 (2认同)

som*_*ome 113

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

var diff =  Math.floor(( Date.parse(str2) - Date.parse(str1) ) / 86400000); 
Run Code Online (Sandbox Code Playgroud)

您可以获得差异天数(如果无法解析其中一个或两个,则为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        )
    };
}
Run Code Online (Sandbox Code Playgroud)

这是我的重构版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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不好回答。当时钟在夏令时前进时,Math.floor() 会让你失去一天。Math.round() 在大多数情况下都会给出正确的答案,但在其他答案中也有更好的选择。 (5认同)

ste*_*bez 94

我建议使用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
Run Code Online (Sandbox Code Playgroud)

  • 就像当一个很好的时候一个警告,它是一个很大的依赖 (9认同)

fue*_*sjr 40

我会继续抓住这个小实用程序,在其中你会找到适合你的功能.这是一个简短的例子:

        <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>
Run Code Online (Sandbox Code Playgroud)


mar*_*ann 23

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)
Run Code Online (Sandbox Code Playgroud)
  1. 设置开始日期
  2. 设置结束日期
  3. 计算差异
  4. 将毫秒转换为天

  • 我很欣赏这样的答案:简短,简单且不需要随机依赖!干杯。 (3认同)
  • 只有我的“timeDiff”返回负数吗?`timeDiff` 不应该是 `(new Date(endDate)) - (new Date(startDate));` 吗? (2认同)

Mic*_*l K 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);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment-with-locales.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


小智 10

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

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

(2013-11-05 00:00:00) - (2013-11-04 10:10:10) < 1 day
Run Code Online (Sandbox Code Playgroud)

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

(2013-11-05 00:00:00) - (2013-11-04 00:00:00) = 1 day
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)


Tim*_*nen 9

最好通过使用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));
Run Code Online (Sandbox Code Playgroud)

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


Noo*_*rJa 9

要计算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);
Run Code Online (Sandbox Code Playgroud)
<h3>DAYS BETWEEN GIVEN DATES</h3>
<p id="demo"></p>
Run Code Online (Sandbox Code Playgroud)


小智 9

可以使用以下公式计算在不同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);
Run Code Online (Sandbox Code Playgroud)


nki*_*tku 7

单线和小型

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')
Run Code Online (Sandbox Code Playgroud)

对于打字稿

const diff = (from: string, to: string) => Math.floor((new Date(from).getTime() - new Date(to).getTime()) / 86400000);
Run Code Online (Sandbox Code Playgroud)


Tol*_*mer 6

我认为解决方案不正确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)
    };
}
Run Code Online (Sandbox Code Playgroud)

  • 天可以超过24小时,分钟可以超过60秒.在这些情况下,使用Math.ceil()会过度计算. (4认同)

gui*_* 桂林 6

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

DIFF天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);
}
Run Code Online (Sandbox Code Playgroud)


小智 6

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

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

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

return dayCount; 
}
Run Code Online (Sandbox Code Playgroud)

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


Ara*_*opi 6

var start= $("#firstDate").datepicker("getDate");
var end= $("#SecondDate").datepicker("getDate");
var days = (end- start) / (1000 * 60 * 60 * 24);
 alert(Math.round(days));
Run Code Online (Sandbox Code Playgroud)

jsfiddle示例:)


bor*_*425 6

尝试这个

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  );
Run Code Online (Sandbox Code Playgroud)


kgi*_*kis 5

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


Abd*_*UMI 5

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
Run Code Online (Sandbox Code Playgroud)


小智 5

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()));
Run Code Online (Sandbox Code Playgroud)

  • @ N.Belhadj你可以用简单的div和mod(%)操作替换所有那些while循环 (2认同)

Var*_*Raj 5

简单、容易和复杂。此函数将每 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);
Run Code Online (Sandbox Code Playgroud)