views:

781

answers:

4

Hello I am looking for a way to do proper subtraction between two javascript Date objects and get the day delta.

This is my approach but it fails for todays date as an input:

<script type="text/javascript">
function getDayDelta(incomingYear,incomingMonth,incomingDay){
var incomingDate = new Date(incomingYear,incomingMonth,incomingDay);
var today = new Date();

var delta = incomingDate - today;
var resultDate = new Date(delta);
return resultDate.getDate();
}
//works for the future dates:
alert(getDayDelta(2009,9,10));
alert(getDayDelta(2009,8,19));

//fails for the today as input, as expected 0 delta,instead gives 31:
alert(getDayDelta(2009,8,18));
</script>

What would be a better approach for this ?

A: 

You could call getTime() on each date object, then subtract the later from the earlier. This would give you the number of milliseconds difference between the two objects. From there, it's easy to get to days.

A couple of hiccups to watch for, though: 1) daylight savings time, and 2) ensuring your times are coming from the same time zone.

Robert J. Walker
+6  A: 

(2009,8,18) is NOT August 18th. It's September 18th.

Vijay Dev
The months are a zero-based index. 0 is January.
Jonathan Sampson
This is correct as the date function zero indexes months.
MacAnthony
+2  A: 

The month number in the Date constructor function is zero based, you should substract one, and I think that is simplier to calculate the delta using the timestamp:

function getDayDelta(incomingYear,incomingMonth,incomingDay){
  var incomingDate = new Date(incomingYear,incomingMonth-1,incomingDay),
      today = new Date(), delta;
  // EDIT: Set time portion of date to 0:00:00.000
  // to match time portion of 'incomingDate'
  today.setHours(0);
  today.setMinutes(0);
  today.setSeconds(0);
  today.setMilliseconds(0);

  // Remove the time offset of the current date
  today.setHours(0);
  today.setMinutes(0);

  delta = incomingDate - today;

  return Math.round(delta / 1000 / 60 / 60/ 24);
}


getDayDelta(2008,8,18); // -365
getDayDelta(2009,8,18); // 0
getDayDelta(2009,9,18); // 31
CMS
thanks for the fix but this seems to fail at:getDayDelta(2009,8,19); //should return 1 but returns 0 (it is 18th at my localtime)
Hellnar
Yes, that's because `today` includes the time, see my edit...
CMS
@Crib: The problem is that `incomingDate` has a time portion of 0 hours, 0 minutes, 0 seconds and 0 milliseconds. You have to do the same to `today` or you will get partial days for a day ahead/behind. I've edited the answer to reflect the change.
Grant Wagner
@CMS: You have to remove everything (hours, minutes, seconds and milliseconds), otherwise you get deltas of 0.99991513...
Grant Wagner
@Grant Wagner: That's why I'm using Math.round in the return statement.
CMS
thanks alot for taking your time!
Hellnar
A: 

This will work better, but it doesn't properly deal with negative result values. You might want to simply parse the values yourself and deal with them.

function getDayDelta(incomingYear,incomingMonth,incomingDay){
var incomingDate = new Date(incomingYear,incomingMonth-1,incomingDay);
var today =   new Date();
today = new Date(Date.parse(today.format("yyyy/MM/dd")));

var delta = incomingDate - today;
if (delta == 0) { return 0; }
var resultDate = new Date(delta);
return resultDate.getDate();
}
//works for the future dates:
alert(getDayDelta(2009,9,10));
alert(getDayDelta(2009,8,19));
alert(getDayDelta(2009, 8, 18));
John Fisher
format is not a function http://is.gd/2n46k
CMS
Then why does it work? (My environment is ASP.NET.)
John Fisher
Yes, the ASP .NET Ajax Framework extends the client-side Date object
CMS