Reputation: 805
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
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
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
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
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