How to calculate number of days between two dates?

Solution 1:

Here is a quick and dirty implementation of datediff, as a proof of concept to solve the problem as presented in the question. It relies on the fact that you can get the elapsed milliseconds between two dates by subtracting them, which coerces them into their primitive number value (milliseconds since the start of 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"/>

You should be aware that the "normal" Date APIs (without "UTC" in the name) operate in the local timezone of the user's browser, so in general you could run into issues if your user is in a timezone that you don't expect, and your code will have to deal with Daylight Saving Time transitions. You should carefully read the documentation for the Date object and its methods, and for anything more complicated, strongly consider using a library that offers more safe and powerful APIs for date manipulation.

  • Numbers and Dates -- MDN JavaScript Guide
  • Date -- MDN JavaScript reference

Also, for illustration purposes, the snippet uses named access on the window object for brevity, but in production you should use standardized APIs like getElementById, or more likely, some UI framework.

Solution 2:

As of this writing, only one of the other answers correctly handles DST (daylight saving time) transitions. Here are the results on a system located in California:

                                        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

Although Math.round returns the correct results, I think it's somewhat clunky. Instead, by explicitly accounting for changes to the UTC offset when DST begins or ends, we can use exact arithmetic:

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

Explanation

JavaScript date calculations are tricky because Date objects store times internally in UTC, not local time. For example, 3/10/2013 12:00 AM Pacific Standard Time (UTC-08:00) is stored as 3/10/2013 8:00 AM UTC, and 3/11/2013 12:00 AM Pacific Daylight Time (UTC-07:00) is stored as 3/11/2013 7:00 AM UTC. On this day, midnight to midnight local time is only 23 hours in UTC!

Although a day in local time can have more or less than 24 hours, a day in UTC is always exactly 24 hours.1 The daysBetween method shown above takes advantage of this fact by first calling treatAsUTC to adjust both local times to midnight UTC, before subtracting and dividing.

1. JavaScript ignores leap seconds.

Solution 3:

The easiest way to get the difference between two dates:

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

You get the difference days (or NaN if one or both could not be parsed). The parse date gived the result in milliseconds and to get it by day you have to divided it by 24 * 60 * 60 * 1000

If you want it divided by days, hours, minutes, seconds and milliseconds:

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

Here is my refactored version of James version:

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

Solution 4:

I recommend using the moment.js library (http://momentjs.com/docs/#/displaying/difference/). It handles daylight savings time correctly and in general is great to work with.

Example:

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

Solution 5:

Steps

  1. Set start date
  2. Set end date
  3. Calculate difference
  4. Convert milliseconds to days

Native JS

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

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

Comment

I know this is not part of your questions but in general, I would not recommend doing any date calculation or manipulation in vanilla JavaScript and rather use a library like date-fns, Luxon or moment.js for it due to many edge cases.


Using a library

Date-fns

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

const differenceInDays = require('date-fns/differenceInDays');

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

const diffInDays = differenceInDays(new Date(endDate), new Date(startDate));

Luxon

https://moment.github.io/luxon/docs/class/src/datetime.js~DateTime.html#instance-method-diff

const { DateTime } = require('luxon');

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

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

Moment.js

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

const moment = require('moment');

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

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

Examples on RunKit

https://runkit.com/marcobiedermann/5f573e211e85e7001a37ab00