Here is a solution for finding the difference between two dates. The strategy is to convert strings to date objects, then calculate the difference and return an array of values for years, months, days, etc.
I've added a parameter for "precise" so that by default it returns a value in whole days (e.g. 2013-08-13T23:59:59Z to 2013-08-14T00:00:01Z is one day) or precise (where the above difference is 2 seconds).
// Expects start date to be before end date
// Default is to deal in whole days. For precise differences
// (hours, minutes and seconds), set precise to true
function dateDifference(start, end, precise) {
var timeDiff, years, months, days, hours, minutes, seconds;
// Copy date objects so don't modify originals
var s = new Date(+start);
var e = new Date(+end);
console.log(s, e);
// If not precise, set h,m,s to zero
if (!precise) {
s.setUTCHours(0,0,0,0);
e.setUTCHours(0,0,0,0);
console.log(s, e);
}
// Get estimate of year difference
years = e.getUTCFullYear() - s.getUTCFullYear();
// Add difference to start, if greater than end, remove one year
// Note start from restored start date as adding and subtracting years
// may not be symetric
s.setFullYear(s.getUTCFullYear() + years);
if (s > e) {
--years;
s = new Date(+start);
s.setFullYear(s.getUTCFullYear() + years);
}
// Get estimate of months
months = e.getUTCMonth() - s.getUTCMonth();
months += months < 0? 12 : 0;
// Add difference to start, adjust if greater
s.setUTCMonth(s.getUTCMonth() + months);
if (s > e) {
--months;
s = new Date(+start);
s.setUTCFullYear(s.getUTCFullYear() + years);
s.setUTCMonth(s.getUTCMonth() + months);
}
// Get remaining time difference
timeDiff = e - s;
days = timeDiff / 8.64e7 | 0;
hours = (timeDiff % 8.64e7) / 3.6e6 | 0;
minutes = (timeDiff % 3.6e6) / 6e4 | 0;
seconds = ((timeDiff % 6e4) / 1e3).toFixed(3);
console.log(years, months, days, hours, minutes, seconds);
return [years, months, days, hours, minutes, seconds];
}
// Simple caluculation of days between two ES5 date objects
function daysDifference(start,end) {
return ((end - start) / 8.64e7).toFixed(2);
}
// Expects input in ISO8601 format: yyyy-mm-ddThh:mm:ss.sssZ
function dateFromString(s) {
s = s.split(/\D/);
s[6] = s[6]? ('0.'+ s[6]) * 1000 : 0;
return new Date(Date.UTC(s[0],--s[1],s[2],s[3],s[4],s[5],s[6]));
}
function getDateDiff(start, end, precise) {
var d = dateDifference(dateFromString(start), dateFromString(end), precise);
return d[0] + ' years, ' + d[1] + ' months, ' + d[2] + ' days' +
(precise? ', ' + d[3] + ' hours, ' + d[4] + ' minutes and ' + d[5] + ' seconds' : '') ;
}
function getDaysDiff(start, end) {
var d = daysDifference(dateFromString(start), dateFromString(end));
return d + ' days';
}
</script>
<!-- Some HTML to show how to use it -->
<form onsubmit="this.doCalc.onclick(); return false;">
<label for="startDate">Start date (yyyy-mm-dd)<input name="startDate" id="startDate"
value="2012-08-09T22:15:03.22" size="25"></label>
<br>
<label for="endDate">End date (yyyy-mm-dd)<input name="endDate" id="endDate"
value="2013-08-13T12:10:03.22" size="25"></label>
<br>
<label for="dateDifference">Date difference: <input name="dateDifference" readonly size="100"></label>
<br>
<label for="daysDifference">Days difference: <input name="daysDifference" readonly size="100"></label>
<br>
<label for="precise"><input type="checkbox" value="precise" name="precise" id="precise">Precise?</label>
<br>
<input type="button" value="Calculate…" name="doCalc" onclick="
this.form.dateDifference.value = getDateDiff(this.form.startDate.value, this.form.endDate.value,
this.form.precise.checked);
this.form.daysDifference.value = getDaysDiff(this.form.startDate.value, this.form.endDate.value);
">
<input type="reset">
</form>