P粉9680081752023-08-24 14:38:40
As of this writing, only one of the other answers correctly handles DST (Daylight Savings Time) conversion. 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 result, I think it's a bit clunky. Instead, by explicitly accounting for the change in UTC offset when DST starts or ends, we can use precise 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()));
JavaScript date calculations are tricky because Date
objects internally store UTC time, 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) stored as 3/11/2013 7:00 AM UTC. On this day, local time from midnight to midnight is only 23 hours ahead of UTC!
While a day in local time can be more or less than 24 hours long, a day in UTC is always exactly 24 hours long. 1 The daysBetween
method shown above takes advantage of this by first calling treatAsUTC
to adjust both local times to midnight UTC, then subtracting and dividing. This fact.
1. JavaScript ignores leap seconds.
P粉1868974652023-08-24 12:44:32
Here is a quick and dirty
implementation of datediff as a proof of concept for solving the problem posed in the question. It relies on the fact that you can get the number of milliseconds that elapsed between two dates by subtracting them, which coerces them to their original numerical values (number of milliseconds since early 1970).
/** * 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"/>