Rico Ocepek
Rico Ocepek

Reputation: 805

Calculate difference between dates in javascript

I am aware that this question was asked multiple times before but the suggested solutions were always something like

var diff = date1 - date2;

My problem is that I want to get the difference in years, months, day, ... ,seconds.

So for example 5y 3m 39d 12h 39i 32s

But simply dividing the difference is too inaccurate for my purpose. So I can't assume that every month has 30.4375*24*60*60*1000 milliseconds.

I need the exact difference! So if date1 is the 1st of february and date2 is the 1st of march, it should display 1m not 28d (or 29d in leap years)!

Thank you.

Upvotes: 0

Views: 2190

Answers (4)

Carsten Massmann
Carsten Massmann

Reputation: 28196

Not using any library you could do

function mydiff(aa,bb){var a,b;
 if(aa<bb) a=aa,b=bb;
 else      a=bb,b=aa;
 var am=a.getMonth(),ay=a.getFullYear();
 var dd=b.getDate()-a.getDate();
 var dm=b.getMonth()-am-(dd<0?1:0);
 return b.getFullYear()-ay-(dm<0?1:0)+'y, '
      + ((12+dm)%12)+'m, '
      +((dd<0?new Date(ay, am+1, 0).getDate():0)+dd)+'d';
}

dd contains the difference 'b minus a in days of month' which can be negative. In that case the month-difference dm has to be reduced by 1 and the (negative) day-difference must be increased by the number of days of the preceding month of date b. I got the formula for "number of days in a particular month" from here. Similar action has to take place with the month- and year-differences dm and dm.

A few samples:

mydiff(new Date(2014,1,2),new Date(2014,2,1)) // "0y, 0m, 27d"
mydiff(new Date(2012,1,1),new Date(2012,2,1)) // "0y, 1m, 0d"  (leap year)
mydiff(new Date(2012,1,2),new Date(2012,2,1)) // "0y, 0m, 28d" (leap year)
mydiff(new Date(2014,11,31),new Date(2015,0,1)) // "0y, 0m, 1d" (different years)
mydiff(new Date(2012,10,30),new Date(2013,1,28)) // "0y, 2m, 28d" (different years)

The last example shows that this kind of "calculation" has its limits: compared to "normal" months 28 days are not a full month. On the other hand, compared to the current month February 28 days is a full month. So it could also be argued that a correct response should be "0y, 3m, 0d".

Upvotes: -1

Pluto
Pluto

Reputation: 3026

First you need to find out which date is bigger, subtract the dates, and if they turn out to be negative borrow from the larger digit (similar to elementary multi-digit subtraction).

function DateDiff(a,b){
    if(b>a){ // We want a-b to be positive
        var c=b;
        b=a;
        a=c;
    }
    var s=a.getSeconds()-b.getSeconds();
    var mi=a.getMinutes()-b.getMinutes();
    var h=a.getHours()-b.getHours();
    var d=a.getDate()-b.getDate(); // Subtract days
    var m=a.getMonth()-b.getMonth(); // Subtract months
    var y=a.getYear()-b.getYear(); // Subtract years
    if(s<0){
        mi--;
        s+=60;
    }
    if(mi<0){
        h--;
        mi+=60;
    }
    if(h<0){
        d--;
        h+=24;
    }
    if(d<0){ // Need to borrow from months
        m--;
        d+=new Date(1900+b.getYear(),1+b.getMonth(),0).getDate();
    }if(m<0){ // Need to borrow from years
        y--;
        m+=12;
    }
    return [y,m,d,h,mi,s];
}
console.log('Mar 1 - Feb 2 (Leap Year):', DateDiff(new Date(2016,1,2),new Date(2016,2,1)));
console.log('Mar 1 - Feb 2 (Reg Year): ',DateDiff(new Date(2015,1,2),new Date(2015,2,1)));
console.log('Feb 1, 2017 - Feb 2, 2016: ',DateDiff(new Date(2017,1,1),new Date(2016,1,2)));
console.log('5:00 - 4:59: ', DateDiff(new Date(2015,7,1,17), new Date(2015,7,1,16,59)));

Upvotes: 1

Tillman32
Tillman32

Reputation: 416

You can use moment.js to achieve this: ( MomentJS Doc )

var start = moment(date1);
var end = moment(date2);
var diff = end.diff(start)

If you want specific things like difference in days, you can do:

var diff = end.diff(start, 'days')

Upvotes: 1

nurdyguy
nurdyguy

Reputation: 2945

For what you are describing, you will want to hold the year/month/day in three different variables and directly compare the years using

    var yeardiff = date1.GetFullYear() - date2.GetFullYear();
    var monthdiff = date1.GetMonth() - date2.GetMonth();
    var daydiff = date1.GetDate() - date2.GetDate();

However, you are going to have to do a lot of checking in this. For example, 8/2/2012 - 7/20/2012 is going to give you a 1 month and -18 days, then you have to convert that into days based on the number of days in July. Because of these issues, the other conversion in the OP is actually easier.

Upvotes: 0

Related Questions