0

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.

Rico Ocepek
  • 767
  • 6
  • 20

4 Answers4

1

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')
Tillman32
  • 416
  • 4
  • 9
  • I like this solution but if I do `end.diff(start, 'days')`, I actually just want to get the days which don't fit in a full month / year but in my test it told me that there are 160 days left.. Is there a way to do this? – Rico Ocepek Jul 27 '15 at 15:58
  • I'm a little confused with what you want, however going off of this statement from you " So if date1 is the 1st of february and date2 is the 1st of march, it should display 1m not 28d", you could use the 'months' filter, like so: https://jsfiddle.net/dsdoj67f/ - Long story short, try: end.diff(start, 'months') – Tillman32 Jul 27 '15 at 16:47
  • Yes, i've already tested this BUT i want the difference in the format 'y m d h m s'.. You already explained how to get the months but how would i get the days whicht don' t fill a complete month? – Rico Ocepek Jul 27 '15 at 17:12
1

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)));
Pluto
  • 2,900
  • 27
  • 38
  • I've testet it but the results are slightly wrong.. PHP has a native method for calculating this and the results don't match exactly.. – Rico Ocepek Jul 27 '15 at 17:42
  • Which dates are you subtracting that come up with the wrong results? – Pluto Jul 27 '15 at 17:51
  • `DateDiff(new Date("2015-07-27"), new Date("2016-01-06"));` returns `[0,5,10]` but should return `[0,5,9]` – Rico Ocepek Jul 27 '15 at 18:00
  • I forgot about the hours, sorry, probably your solution is right but shows 1 day more because of the hours – Rico Ocepek Jul 27 '15 at 18:01
  • @RicoOcepek Do you want to be able to enter a date that has time values included and display the difference of dates only? – Pluto Jul 27 '15 at 18:05
  • As i mentioned in my question I want the difference in the format 'y m d h m s'. I tried to extend your function and it now returns `[0, 5, 10, -20, -5, -18]` which looks good! I just need to add 24 and remove 1 day and the results should be fine! – Rico Ocepek Jul 27 '15 at 18:08
  • I did the same changes as you did and it works just great! Thanks! – Rico Ocepek Jul 27 '15 at 18:22
0

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.

nurdyguy
  • 2,876
  • 3
  • 25
  • 32
-1

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".

Community
  • 1
  • 1
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
  • OK, I see that the downvote *was* justified in a way: there was still a flaw in the formula, when two dates from different years were compared. This problem has now been fixed, so check it out again! – Carsten Massmann Jul 27 '15 at 21:20