Calculate Duration Between Two Dates Using Javascript

Basically I want to have two dates, for example:

var startDate = new Date("01/01/2001 01:00:00"); var currentDate = new Date(); 

Then I want to get the duration by subtracting startDate from currentDate and displaying it in the form: a years b months (days) c days. d hour e seconds (s) s) .

My problem so far has been that if you take the shortcut, that is:

 var duration = currentDate.getTime() - startDate.getTime(); var seconds = duration / 1000; var minutes = duration / 1000 / 60; 

etc...

Then you get a false duration, because, for example, months are not always 30 days, years are not always 365 days (leap years), etc. Not to mention the fact that I once did this in a year.

I browsed the web pages and through various messages in StackOverflow, but I could not find a working example of a JavaScript method that accurately subtracts one date from another and allows you to get details (year, month, day, hour, minute, second) from the date of the result.

There is a website that can already do this exactly the way I would like to do it: http://www.timeanddate.com

+4
source share
6 answers

There is no obvious simple solution to the problem if you want to get the “right” result because the months have a different number of days.

But at the same time, the human brain is becoming increasingly sloppy when it comes to large date ranges. So “1 year, 11 months” is almost as good as “almost two years.” Therefore, before you start with a 100% correct decision, ask yourself if the result will be good enough when you fake it and just use the 30-day months.

If this is really not an option: get rid of hours and minutes; they will just be confusing. Create two dates that start at midnight (i.e. HH: MM: SS 00:00:00).

Now the question is, how many days, months and years between them? It depends. The time between June 1 and August 31 is almost two months, but there is no month between the two dates. It is 61 days, 0 months . Or 1 month, 30 days ? What is the "right"?

A mathematically correct solution will give you results with a difference of 61 days, which users will annoy.

A human decision is not mathematically correct, so you have to code a heuristic that fakes a human sense of time.

This is why so many sites say "more than one month" if some dates differ by more than 30 days and continue to "six months," "year" (for something between 330 and 380 days) and "more than a year," etc. d. They use the careless human brain to their advantage, instead of trying to come up with an “exact” result (which a) is not very useful and b) no one agrees on what such “exact” should mean).

+2
source

I struggled with this exact problem for several days. Finally did something that I think is working. Looks like shit now, sloppy comments and stupid variable names, and I'll do the cleanup tomorrow. But I decided that I would publish it anyway if necessary.

EDIT: I cleared the code and made its essence. Have a look here: https://gist.github.com/4705863

EDIT2: Damn it, found a mistake. I'm on it. Bug fixed, now works great!

  // Time difference function function timeDiff(start, end) { //today, now! //Get the diff var diff = end - start; //Create numbers for dividing to get hour, minute and second diff var units = [ 1000 * 60 * 60 *24, 1000 * 60 * 60, 1000 * 60, 1000 ]; var rv = []; // h, m, s array //loop through d, h, m, s. we are not gonna use days, its just there to subtract it from the time for (var i = 0; i < units.length; ++i) { rv.push(Math.floor(diff / units[i])); diff = diff % units[i]; } //Get the year of this year var thisFullYear = end.getFullYear(); //Check how many days there where in last month var daysInLastMonth = new Date(thisFullYear, end.getMonth(), 0).getDate(); //Get this month var thisMonth = end.getMonth(); //Subtract to get differense between years thisFullYear = thisFullYear - start.getFullYear(); //Subtract to get differense between months thisMonth = thisMonth - start.getMonth(); //If month is less than 0 it means that we are some moths before the start date in the year. // So we subtract one year, and add the negative number (month) to 12. (12 + -1 = 11) subAddDays = daysInLastMonth - start.getDate(); thisDay = end.getDate(); thisMonth = thisMonth - 1; if(thisMonth < 0){ thisFullYear = thisFullYear - 1; thisMonth = 12 + thisMonth; //Get ends day of the month } //Subtract the start date from the number of days in the last month, add add the result to todays day of the month subAddDays = daysInLastMonth - start.getDate(); subAddDays = thisDay + subAddDays; if(subAddDays >= daysInLastMonth){ subAddDays = subAddDays - daysInLastMonth; thisMonth++; if (thisMonth > 11){ thisFullYear++; thisMonth = 0; } } return { years: thisFullYear, months: thisMonth, days: subAddDays, hours: rv[1], minutes: rv[2], seconds: rv[3] }; } //The start date/From date. Here i add one hour to offset it. //var start = new Date(1814, 3, 20, 1); //The end date. today, now! //var end = new Date(); //Get the difference //var d = timeDiff(start, end); // Log that bitch //console.log('years: '+ d.years + '. months: '+ d.months + '. days: ' + d.days + '. hours:' +d.hours+ '. minutes:' + d.minutes + '. seconds: ' + d.seconds); 
+1
source

http://www.w3schools.com/jsref/jsref_obj_date.asp

 myDate.UTC() // get the number of milliseconds since the Unix epoch 

So,

 delta_ms = laterDate.UTC() - earlierDate.UTC(); delta_days = Math.round(delta_ms / (1000 * 60 * 60 * 24)); 

If you need months and years, you need to indicate whether you want a difference in the calendar (for example, from May 1 to June 1 - 1 month, but from February 28 to March 30 - ??) or against the "standard" year, for example, 365 days and 30 day months, etc.

It is not easy, even if it seems that it should be so. For example, in the financial sector, there are at least 5 ways of calculating the gap between two dates, using standard months or not, and using standard dates or not. Creating a date after a certain date is easy (1 calendar month after February 1 - March 1), but you will not be able to go back because the display is not 1: 1.

Also, note that this is an absolute value that does not require adjustment for leap years, leap seconds, daylight saving time, time zones, and all other time formats.

0
source

You can also consider these cases. Consider the 2 dates of 2nd Mar 2008 and 5th Jun 2013 .

  Mar 2008 ________########################### 2009 ################################### 2010 ################################### 2011 ################################### 2012 #################################### (leap) 2013 ###############-------------------- Jun 

You can subtract interim years (e.g. 2009, 2010, 2011, 2012). Now 2012 is a leap year, but it does not matter, because it will be taken into account for years, not months.

Years = 4

Now you stay with that

  2 Mar 08 ____################################ Apr 08 #################################### May 08 ##################################### Jun 08 #################################### Jul 08 ##################################### Aug 08 ##################################### Sep 08 #################################### Oct 08 ##################################### Nov 08 #################################### Dec 08 ##################################### Jan 12 ##################################### Feb 12 ################################### Mar 12 ##################################### Apr 12 #################################### May 12 ##################################### Jun 12 #########---------------------------- 5 

Just count the full months. It doesn't matter how many days they contain. They are counted in months, not in days.

Months = 14

  2 Mar 08 ____################################ Jun 12 #########---------------------------- 5 

Now count the remaining days in Mar2008 and Jun2012 (excluding the end dates). Here the counter is 29 (Mar) + 4 (June) = 33.

Days = 33

But 33 days seems strange, since it can be converted to 1 month + several days. If this happens, the question arises of which month to choose - either Mar (31 days), June (30 days), or simply reduce 30 days to add a month. I think that given the huge differences, this is hardly relevant. If we look at March, the difference will be

4 Years 15 Months 2 Days or just 5 Years 3 Months 2 Days

The same approach can be continued for a while.

EDITED

 Let `date1` be greater than `date2` Let max(month) gives the total days in the month years = date1.year - date2.year - 1; months = date1.month - date2.month - 1; days = (max(date2.month) - date1.day) + (date2.day - 1); if(days >= 30) //Here you can take totals days in date1 or date2 { month++; days-=30; } while(month >= 12) //Here month can reach a value of 24 because it can be incremented above too { years++; month-=12; } print("Difference is " + years + " years " + month + " months " + days + " days"); 
0
source

Leaving an answer for yourself in the future

Just use the moment and its duration plugin

and use for example

 moment.duration(moment('then').diff(moment('now'))).format('d [Days] hh:mm:ss') 

works

0
source
 var years = currentDate.getYear() - startDate.getYear(); var months = currentDate.getMonth() - startDate.getMonth(); ... 
-1
source

Source: https://habr.com/ru/post/1442732/


All Articles