1

I am trying to determine the time elapsed between 2 dates using javascript. An example would be: "I quit smoking on January 5, 2008 at 3 A.M., how many years, months, and hours has elapsed since I quit?".

So my thoughts were:

  1. Get "quit" date
  2. Get current date
  3. Convert to time (milliseconds)
  4. Find the difference
  5. Create a new date using the difference
  6. Extract the years, months, etc. from that date

Well, it is acting strange and I can't pin point why. Any insight?

//create custom test date
var d1 = new Date(2012, 8, 28, 13, 14, 0, 0);
//create current date
var d2 = new Date();
//get date times (ms)
var d1Time = (d1.getTime());
var d2Time = (d2.getTime());
//calculate the difference in date times
var diff = d2 - d1;
//create a new date using the time differences (starts at Jan 1, 1970)
var dDiff = new Date();
dDiff.setTime(diff);
//chop off 1970 and get year, month, day, and hour
var years = dDiff.getFullYear() - 1970;
var months = dDiff.getMonth();
var days = dDiff.getDate();
var hours = dDiff.getHours();

You can see it in action at this temporary host.

j08691
  • 204,283
  • 31
  • 260
  • 272
Dan
  • 11
  • 2
  • 1
    Try using timestamp (timestamp_now - previous_timestamp) then convert timestamp into date. – poudigne Oct 04 '12 at 19:14
  • @Bill, probably overkill if this is all they want to achieve, but neat tool. May use that myself. – Dan Oct 04 '12 at 19:16

5 Answers5

0

Why don't you just do the math to calculate the values? What you are putting into Date when you do dDiff.setTime(diff); is meaningless to you. That is just going to give you the date diff ms from the epoch.

thatidiotguy
  • 8,701
  • 13
  • 60
  • 105
  • I understand now. I was trying to be able to extract the months elapsed as well. That will clearly not work by creating a new Date object using the diff value. Thanks. – Dan Oct 04 '12 at 19:24
0

Changing part of your code may solve your problem. jsfiddle

var start = new Date(0); // pivote point of date.
var years = dDiff.getFullYear() - start.getFullYear();
var months = dDiff.getMonth() -  start.getMonth();
var days = dDiff.getDate() -  start.getDate();
var hours = dDiff.getHours() - start.getHours();;
console.log(years, months, days, hours);​

But you have to manipulate these values based on there value( they may come negative).

Anoop
  • 23,044
  • 10
  • 62
  • 76
0

Date represents a particular point in time, not a timespan between two dates. You are creating a new date by setting dDiff milliseconds ellapsed since the unix epoch.

Once you have the milliseconds ellapsed, you should extract the information you need by dividing it. See this question.

May I recomend taking a look at Moment.js?

Community
  • 1
  • 1
Nathan
  • 4,017
  • 2
  • 25
  • 20
  • I see what you mean. I'd like to be able to determine months elapsed as well (which I guess why I thought creating a new Date object would help). This will require me take month lengths (30,31,28,29) into account. – Dan Oct 04 '12 at 19:23
  • Take a look at moment.js - it will probably suit your needs =) – Nathan Oct 04 '12 at 19:33
  • Oh, moment.js is glorious. Thank you very much. – Dan Oct 04 '12 at 19:49
0

This won't be accurate as it does not take into account the leap dayys. Other than that, it is working correctly and I don't see any problem. The time difference is roughly 6.5 days. Taking into account timezone and the fact that 0 is Jan 1st, the value I see is as expected.

The accurate solution would be to

  • Convert the time difference into days
  • Subtract the number of leap years elapsed since the specified date
  • Divide the remaining by 365 to get the number of days
  • Create an array with the day count of each month (without considering leap days) and loop through the elapsed months, subtracting the day count for the completed months. The number of iterations will be your month count
  • The remainder is your day count
Joyce Babu
  • 19,602
  • 13
  • 62
  • 97
0

Various notes:

  • new Date(2012, 8, 28, 13, 14, 0, 0); is 28 September 2012 13:14:00 (not August if you would it)
  • new Date(0) returned value is not a constant, because of the practice of using Daylight Saving Time.
  • dDiff.getMonth(); return 0 for Jan, 1 for Feb etc.
  • The begin of date (1 Jan 1970) begin with 1 so in difference you should subtract this.

I think the second point is your mistake.

According with your algorithm, try this:

// create date in UTC
//create custom test date
var dlocaltime = new Date(2012, 8, 28, 13, 14, 0, 0);
var d1 = new Date(dlocaltime.getUTCFullYear(),dlocaltime.getUTCMonth(), dlocaltime.getUTCDate(), dlocaltime.getUTCHours(),dlocaltime.getUTCMinutes(),dlocaltime.getUTCSeconds());
//create current date
var now = new Date();
var d2 = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(),  now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
console.log(d1);
console.log(d2);
//get date times (ms)
var d1Time = (d1.getTime());
var d2Time = (d2.getTime());


//calculate the difference in date times
var diff = d2 - d1;
//create a new date using the time differences (starts at Jan 1, 1970)
var dDiff = new Date();
dDiff.setTime(diff);
//chop off 1970 and get year, month, day, and hour
var years = dDiff.getUTCFullYear() - 1970;
var months = dDiff.getUTCMonth();
var days = dDiff.getUTCDate()-1; // the date of new Date(0) begin with 1 
var hours = dDiff.getUTCHours();
var minutes = dDiff.getUTCMinutes();
var seconds = dDiff.getUTCSeconds();
console.log("Years:"+years);
console.log("months:"+months);
console.log("days:"+days);
console.log("hours:"+hours);
console.log("minutes:"+minutes);
console.log("seconds:"+seconds);
Luca Rainone
  • 16,138
  • 2
  • 38
  • 52