Domanda

I've been working on this script to get the difference between 2 dates. But the hours will mess up the script (http://jsfiddle.net/HuGvd/).

When the script enters a new month new the same day the script stops working correctly. I've also tried adding minutes to this script with no luck really need help with this one guys.

function getDateDiff(timestamp) {
if (null === timestamp || timestamp === "" || timestamp === "undefined") return "?";
var splitDate = ((timestamp.toString().split('T'))[0]).split('-');
var splitTime = ((timestamp.toString().split('T'))[1]).split(':');
var d1 = new Date();
var d1Y = d1.getFullYear();
var d2Y = parseInt(splitDate[0], 10);
var d1M = d1.getMonth() + 1;
var d2M = parseInt(splitDate[1], 10);
var d1D = d1.getDate();
var d2D = parseInt(splitDate[2], 10);
var d1H = d1.getHours();
var d2H = parseInt(splitTime[0], 10);
var diffInHours = (d1H + 24 * d1D + 30) - (d2H + 24 * d2D + 30);
if (diffInHours < 24) return diffInHours + " hour";
var diffInDays = (d1D + 30 * d1M + 12) - (d2D + 30 * d2M + 12);
if (diffInDays < 7) return diffInDays + " days";
else if (diffInDays >= 7 && diffInDays < 14) return "1 week";
else if (diffInDays >= 14 && diffInDays < 30) return Math.floor(diffInDays / 7) + " weeks";
var diffInMonths = (d1M + 12 * d1Y) - (d2M + 12 * d2Y);
if (diffInMonths <= 1) return "1 month";
else if (diffInMonths < 12) return diffInMonths + " months";
var diffInYears = Math.floor(diffInMonths / 12);
if (diffInYears <= 1) return "1 year";
else if (diffInYears < 12) return diffInYears + " years";
}
È stato utile?

Soluzione

Date/time functionality is extremely complex with more edge cases than you can possibly cover... don't roll your own solution, use built-in functionality. You can find the number of milliseconds between two dates in javascript like this:

var now = new Date();
var then = new Date(timestamp);

var diffMS = now - then;    

From there, it's not too difficult to convert to whatever unit your want based on how you want to display it.

http://jsfiddle.net/AMDXq/

As a side note, this is a fairly common problem. I haven't looked, but I'm sure there's a plugin or library out there for this.

Altri suggerimenti

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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top