[javascript] How to calculate date difference in JavaScript?

Expressions like "difference in days" are never as simple as they seem. If you have the following dates:

d1: 2011-10-15 23:59:00
d1: 2011-10-16 00:01:00

the difference in time is 2 minutes, should the "difference in days" be 1 or 0? Similar issues arise for any expression of the difference in months, years or whatever since years, months and days are of different lengths and different times (e.g. the day that daylight saving starts is 1 hour shorter than usual and two hours shorter than the day that it ends).

Here is a function for a difference in days that ignores the time, i.e. for the above dates it returns 1.

/*
   Get the number of days between two dates - not inclusive.

   "between" does not include the start date, so days
   between Thursday and Friday is one, Thursday to Saturday
   is two, and so on. Between Friday and the following Friday is 7.

   e.g. getDaysBetweenDates( 22-Jul-2011, 29-jul-2011) => 7.

   If want inclusive dates (e.g. leave from 1/1/2011 to 30/1/2011),
   use date prior to start date (i.e. 31/12/2010 to 30/1/2011).

   Only calculates whole days.

   Assumes d0 <= d1
*/
function getDaysBetweenDates(d0, d1) {

  var msPerDay = 8.64e7;

  // Copy dates so don't mess them up
  var x0 = new Date(d0);
  var x1 = new Date(d1);

  // Set to noon - avoid DST errors
  x0.setHours(12,0,0);
  x1.setHours(12,0,0);

  // Round to remove daylight saving errors
  return Math.round( (x1 - x0) / msPerDay );
}

This can be more concise:

_x000D_
_x000D_
/*  Return number of days between d0 and d1._x000D_
**  Returns positive if d0 < d1, otherwise negative._x000D_
**_x000D_
**  e.g. between 2000-02-28 and 2001-02-28 there are 366 days_x000D_
**       between 2015-12-28 and 2015-12-29 there is 1 day_x000D_
**       between 2015-12-28 23:59:59 and 2015-12-29 00:00:01 there is 1 day_x000D_
**       between 2015-12-28 00:00:01 and 2015-12-28 23:59:59 there are 0 days_x000D_
**        _x000D_
**  @param {Date} d0  - start date_x000D_
**  @param {Date} d1  - end date_x000D_
**  @returns {number} - whole number of days between d0 and d1_x000D_
**_x000D_
*/_x000D_
function daysDifference(d0, d1) {_x000D_
  var diff = new Date(+d1).setHours(12) - new Date(+d0).setHours(12);_x000D_
  return Math.round(diff/8.64e7);_x000D_
}_x000D_
_x000D_
// Simple formatter_x000D_
function formatDate(date){_x000D_
  return [date.getFullYear(),('0'+(date.getMonth()+1)).slice(-2),('0'+date.getDate()).slice(-2)].join('-');_x000D_
}_x000D_
_x000D_
// Examples_x000D_
[[new Date(2000,1,28), new Date(2001,1,28)],  // Leap year_x000D_
 [new Date(2001,1,28), new Date(2002,1,28)],  // Not leap year_x000D_
 [new Date(2017,0,1),  new Date(2017,1,1)] _x000D_
].forEach(function(dates) {_x000D_
  document.write('From ' + formatDate(dates[0]) + ' to ' + formatDate(dates[1]) +_x000D_
                 ' is ' + daysDifference(dates[0],dates[1]) + ' days<br>');_x000D_
});
_x000D_
_x000D_
_x000D_