Solved

Posted on 2011-05-02

The following j-script below calculates term in years, months and days. However, it is not working when there are leap years within the term. Here is an example of the behavior in the system with the script enabled. Clearly this is a 6 year lease, not a “5 Years, 11 Months, 28 Days” term:.

How I can I add leap year in following code.

here code I am using

/* Function calculates difference between Commencement and Expiry date and displays in the format 'X Yrs, Y Mos, Z Days' */

DateDifference = function(commence, expiry)

{

if(commence == null || expiry == null)

{

return '0 Yrs 0 Mos 0 Days';

}

else

{

// Difference between 2 dates

var diffDate = expiry - commence;

// Years

var years = diffDate/31536000000;

// Months

var months = (diffDate % 31536000000)/2628000000;

// Days

var days = ((diffDate % 31536000000) % 2628000000)/86400000;

// Result string

var result = Math.floor(years) + " Yrs, " + Math.floor(months) + " Mos, " + Math.floor(days) + " Days";

return result;

}

}

Please check the screen shot for more info

Thanks

Masood

Date-difference.docx

How I can I add leap year in following code.

here code I am using

/* Function calculates difference between Commencement and Expiry date and displays in the format 'X Yrs, Y Mos, Z Days' */

DateDifference = function(commence, expiry)

{

if(commence == null || expiry == null)

{

return '0 Yrs 0 Mos 0 Days';

}

else

{

// Difference between 2 dates

var diffDate = expiry - commence;

// Years

var years = diffDate/31536000000;

// Months

var months = (diffDate % 31536000000)/2628000000;

// Days

var days = ((diffDate % 31536000000) % 2628000000)/86400000;

// Result string

var result = Math.floor(years) + " Yrs, " + Math.floor(months) + " Mos, " + Math.floor(days) + " Days";

return result;

}

}

Please check the screen shot for more info

Thanks

Masood

Date-difference.docx

37 Comments

Leap years are every 4 years, except years divisible by 100 unless they are also divisible by 400. (2000 is, 2100 isn't, 2200 isn't, 2300 isn't, 2400 is) so 2096 is before 2104 for leap years.

Also, this will never be entirely accurate in its current state. You're assuming that months have 30.416 days. No months have that.

It may be better to do, and this is not code, just logic:

years = endyear - startyear;

months = endmonth - startmonth; If months < 0 { years--; months=12+months; (the negative creates a number lower than 12) }

days = enddays - startdays; If days < 0 { months--; if months < 0 { years--; months=12-months; } days=(days in the month)-days; }

Is this all going to be client-side processing? If not, use whatever server-side language you're using to do this.

There are dozens of these kinds of things already made: http://ditio.net/2010/05/0

I agree, and if you are going to make this assumption, you may as well also assume that a year has 31557600000ms instead of 31536000000ms. (Since a year is actually closer to 365.25 days.) This might improve the accuracy somewhat, but it won't be exact.

stare date is 1/1/ 2011 and expiry as 12/31/2016 ( dd/mm/yyyy) format

Thanks

Mas

I have not added month checks (1-12) or year checks.

```
<script type='text/javascript'>
//1/1/ 2011 and expiry as 12/31/2016
var startDate='01/01/2011';
var endDate='12/31/2016';
var startExplode=startDate.split('/');
var startYears=parseInt(startExplode[2],10);
var startMonths=parseInt(startExplode[0],10);
var startDays=parseInt(startExplode[1],10);
var endExplode=endDate.split('/');
var endYears=parseInt(endExplode[2],10);
var endMonths=parseInt(endExplode[0],10);
var endDays=parseInt(endExplode[1],10);
startDate=new Date(startDate).getTime();
endDate=new Date(endDate).getTime();
if((startYears < endYears || startMonths < endMonths || startDays < endDays) && startDate < endDate) {
var dateDifference=endDate-startDate;
var datesPerMonth=new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
if(endYears%4==0) { datesPerMonth[2]=29; }
if(endYears%100==0 && endYears%400>0) { datesPerMonth[2]=28; }
if(startDays<=datesPerMonth[startMonths]) {
if(endDays<=datesPerMonth[endMonths]) {
var diffYears=endYears-startYears;
var diffMonths=endMonths-startMonths; if(diffMonths < 0) { diffYears--; diffMonths=(12-diffMonths); }
var diffDays=endDays-startDays; if(diffDays < 0) { diffMonths--; if(diffMonths<0) { diffYears--; diffMonths=(12-diffMonths); } diffDays=datesPerMonth[(endMonths==1?12:(endMonths-1))]-diffDays; }
document.write("Difference: "+diffYears+" years; "+diffMonths+" months; "+diffDays+" days");
}
else { document.write('Bad end'); }
}
else { document.write('Bad start'); }
}
</script>
```

```
<script type='text/javascript'>
//1/1/ 2011 and expiry as 12/31/2016
var startDate='12/01/2011';
var endDate='12/31/2016';
endDate='02/29/2016';
var startExplode=startDate.split('/');
var startYears=parseInt(startExplode[2],10);
var startMonths=parseInt(startExplode[0],10);
var startDays=parseInt(startExplode[1],10);
var endExplode=endDate.split('/');
var endYears=parseInt(endExplode[2],10);
var endMonths=parseInt(endExplode[0],10);
var endDays=parseInt(endExplode[1],10);
startDate=new Date(startDate).getTime();
endDate=new Date(endDate).getTime();
if((startYears < endYears || startMonths < endMonths || startDays < endDays) && startDate < endDate) {
var dateDifference=endDate-startDate;
var datesPerMonth=new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
if(endYears%4==0) { datesPerMonth[2]=29; }
if(endYears%100==0 && endYears%400>0) { datesPerMonth[2]=28; }
if(startDays<=datesPerMonth[startMonths]) {
if(endDays<=datesPerMonth[endMonths]) {
var diffYears=endYears-startYears; // if(endMonths < startMonths || (endMonths == startMonths && endDays < startDays)) { diffYears--; }
var diffMonths=endMonths-startMonths; if(diffMonths < 0) { diffYears--; diffMonths=(12+diffMonths); }
var diffDays=endDays-startDays; if(diffDays < 0) { diffMonths--; if(diffMonths<0) { diffYears--; diffMonths=(12+diffMonths); } diffDays=datesPerMonth[(endMonths==1?12:(endMonths-1))]+diffDays; }
document.write("Difference: "+diffYears+" years; "+diffMonths+" months; "+diffDays+" days");
}
else { document.write('Bad end'); }
}
else { document.write('Bad start'); }
}
</script>
```

Thanks for code.

I have question, time difference between 1/1/ 2011 and 12/31/2016 should be 6 year, but I ran your code I am getting Difference: 5 years; 0 months; 30 days ??

could you please look into it.

Thanks

Mas

Anyway - have a read here http://www.merlyn.demon.co

Also takes me back to http://www.irt.org/script/

Also, in my code the start date is 12/01/2011, not 01/01/2011, which is why you are showing 0 months.

The code checks for leap years.

@mplungjan: the code was used as a complete HTML file, not as a separate script, as implied by the fact it is self executing.

code also checking each year between start and end date (including start date and end date) as leap year ??

Thanks

Mas

Hi Hi Vampireofdarkness,

If I check the date difference between 1/1/2013 and 12/31/2015 , I am getting Difference: 2 years; 11 months; 30 days . Should it be 3 year, 0 month, 0 days

Thanks

Mas

If you want it to show 3 years (ie- one day more than it should) I would suggest changing the code so that you either

1. Subtract one day from the startDate variable (and make sure if you go into negatives to subtract from the months and year accordingly)

2. Add to the endDate variable (also noting the months and years)

3. Add to the diffDays, remembering months and years

No it is NOT.

The year starts at 1/1/2011 00:00:00, but on 12/31/2011 23:59:59 there are ZERO years elapsed still.

You have to wait until January 1 to be able to say "A year has elapsed!".

Also note, when you say that the expiration date is:

12/31/2016

Javascript assuming you mean 12/31/2016 00:00:00, but based on your (wrong) assumptions of elapsed times, what you really mean is 12/31/2016 23:59:59.

But like I said, at 12/31/2016 23:59:59 the sixth year has NOT completed yet. So for your intended purposes, add a day to whatever your end date is and you will get the time frame you want/expect.

1: calculate number of days till the first of next month

2: calculate the number of months till end of year

3: calculate number of years from the 1st of Jan to the 1st of Jan of the end year

4: add months from 1st of Jan of the end year to end month start

5: add days from 1st of end month to end date

TODO: Test if days within same month and months within same year, but it seems a good start :)

```
<script>
/* Attempt on an accurate year month day difference by
Michel Plungjan, javascripts(a)plungjan.name
It will be appreciated if this comment stays */
var aDay = 24*60*60*1000;
var DateDifference = function(commence, expiry) {
if (!commence || !expiry) return '0 Yrs 0 Mos 0 Days';
var months = 0;
var years = 0;
var days = 0;
var start = new Date(Date.parse(commence))
start.setHours(0,0,0,0); // normalise
var end = new Date(Date.parse(expiry));
end.setHours(0,0,0,0); // at midnight
var firstOfNextMonth = new Date(start.getFullYear(),start.getMonth()+1,1,0,0,0,0); // 1st of the next month
var numberOfDaysInStartMonth = new Date(start.getFullYear(),start.getMonth()+1,0,0,0,0,0).getDate();
var daysToNextMonth=0;
for (var i=start.getTime(), n=firstOfNextMonth.getTime();i<n;i+=aDay) {
daysToNextMonth++;
}
if (daysToNextMonth===numberOfDaysInStartMonth) {
days=0;
months++;
}
var monthsToNextYear = 12-(start.getMonth()+1);
months += monthsToNextYear;
if (months === 12) {
months = 0;
years++;
}
if (end.getFullYear() > start.getFullYear()+1) {
for (var i=start.getFullYear()+1, n=end.getFullYear();i<n;i++) {
years++;
}
}
firstOfNextMonth = new Date(end.getFullYear(),end.getMonth()+1,1,0,0,0,0); // 1st of the next month
var numberOfDaysInEndMonth = new Date(end.getFullYear(),end.getMonth()+1,0,0,0,0,0).getDate();
if (end.getDate()===numberOfDaysInEndMonth) {
days=0;
months++;
}
else days += end.getDate()+1; // 24 hours
months += end.getMonth();
if (months === 12) {
months = 0;
years++;
}
return years+" year"+((years==1)?" ":"s ")+months+" month"+((months==1)?" ":"s ")+days+" day"+((days==1)?" ":"s ")
}
alert(DateDifference("02/29/2004","02/28/2007"));
alert(DateDifference("1/1/2013","12/31/2015"));
</script>
```

Sorry for late reply, I was testing it.

I used you code and I am almost there but

It’s not working on months. For example. 1/1/2011 – 1/31/2011 should be 1 month not 30 days

Or 1/1/2011 – 6/30/2011 should be 6 months not 5 months, 29 days

Hi mplungjan,

in your code how we can check leap year ?

Thanks

Masood

@mas1963 - please read above. 1st Jan to 31st Jan is 30 days, not a month (31 days, in this case). If you want to change the output, you need to add one day to the output and change the months and years accordingly. I have said this at least twice.

Modified code, NOTE THAT THIS IS NOT CONTAINED WITHIN A FUNCTION: datesPerMonth moved to the top, added the endDays++; line (Line 17?)

```
<script type='text/javascript'>
var datesPerMonth=new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
var startDate='1/01/2011';
var endDate='12/31/2016';
var startExplode=startDate.split('/');
var startYears=parseInt(startExplode[2],10);
var startMonths=parseInt(startExplode[0],10);
var startDays=parseInt(startExplode[1],10);
var endExplode=endDate.split('/');
var endYears=parseInt(endExplode[2],10);
var endMonths=parseInt(endExplode[0],10);
var endDays=parseInt(endExplode[1],10);
endDays++; if(endDays>datesPerMonth[endMonths]) { endDays=1; endMonths++; if(endMonths==13) { endMonths=1; endYears++; } }
startDate=new Date(startDate).getTime();
endDate=new Date(endDate).getTime();
if((startYears < endYears || startMonths < endMonths || startDays < endDays) && startDate < endDate) {
var dateDifference=endDate-startDate;
if(endYears%4==0) { datesPerMonth[2]=29; }
if(endYears%100==0 && endYears%400>0) { datesPerMonth[2]=28; }
if(startDays<=datesPerMonth[startMonths]) {
if(endDays<=datesPerMonth[endMonths]) {
var diffYears=endYears-startYears; // if(endMonths < startMonths || (endMonths == startMonths && endDays < startDays)) { diffYears--; }
var diffMonths=endMonths-startMonths; if(diffMonths < 0) { diffYears--; diffMonths=(12+diffMonths); }
var diffDays=endDays-startDays; if(diffDays < 0) { diffMonths--; if(diffMonths<0) { diffYears--; diffMonths=(12+diffMonths); } diffDays=datesPerMonth[(endMonths==1?12:(endMonths-1))]+diffDays; }
document.write("Difference: "+diffYears+" years; "+diffMonths+" months; "+diffDays+" days");
}
else { document.write('Bad end'); }
}
else { document.write('Bad start'); }
}
</script>
```

1/1/2011 - 12/31/2016 shows as 6 years, but now 1/1/2011 - 1/1/2016 shows as 5 years and 1 day (which by your method is correct)

Its now working perfectly.

I need final help.

In result variable if years, month or days, any one is zero then in result i don't to show them.

var result = Math.floor(diffYears) + " Yrs, " + Math.floor(diffMonths) + " Mos, " + Math.floor(diffDays) + " Days";

i

Thanks

Masood

```
diffYears=(diffYears>0)?((diffYears==1)?diffYears+' year':diffYears+' years'):'';
diffMonths=(diffMonths>0)?((diffMonths==1)?diffMonths+' month':diffMonths+' months'):'';
diffDays=(diffDays>0)?((diffDays==1)?diffDays+' day':diffDays+' days'):'';
var result = diffYears+' '+diffMonths+' '+diffDays;
```

Change the result output formatting to suit. You can also add Math.floor() into the conditional part if you want to, but it shouldn't be needed.

```
diffYears=(diffYears>0)?((diffYears==1)?Math.floor(diffYears)+' year':Math.floor(diffYears)+' years'):'';
```

If I have

30th of Jan 2004 to 29th of Feb 2004 - is that 1 month 1 day (because it is all of Feb plus one day in Jan)

or is it 1 month (because it is 30 days) or is it 30 days

And if I have

30th of Jan 2005 to 28th of Feb 2005 - is that 1 month 1 day (because it is all of Feb plus one day in Jan)

or 29 days (because it is less than 30 days) or something else?

I also like to thanks mplungjan for your input.

Thanks all.

Thanks

Right now I cheat by adding this to the script

if (start.getFullYear() === end.getFullYear() && (end.getDate()-start.getDa

for (var i=start.getDate();i<=end.g

return formatDiff(0,0,days);

}

function formatDiff(years,months,da

var res = [];

if (years) res.push(years +" year" +((years ==1)?" ":"s "));

if (months) res.push(months+" month"+((months==1)?" ":"s "));

if (days) res.push(days +" day" +((days ==1)?" ":"s "));

return res.join(" ");

}

If I have

var startDate='2/25/2004';

var endDate='3/4/2004';

I get 9 days

if I have

var startDate='2/25/2003';

var endDate='3/4/2003';

I get 8 days

But 25 @00:00 +26+27+28+29+1+2+3 @23:59

is 8 days, no?

You're using a leap year in your first example and a non-leap year in the second.

Also in my opinion the 1st to the 29th of Feb in a leap year is a month and the 1st to the 28th of Feb is a month in a non-leap year

You can't selectively include the last day when calculating, otherwise when booking a holiday you could end up losing a day of your holiday depending on whether you leave on the last day of the month or not. Either you include the last day as a full day, or you don't.

25 - 1 < including

26 - 2

27 - 3

28 - 4

29 - 5

1 - 6

2 - 7

3 - 8 < including

unless of course you talk nights

then you arrive on the 25th and leave on the 4th

By clicking you are agreeing to Experts Exchange's Terms of Use.

Title | # Comments | Views | Activity |
---|---|---|---|

Creating a Batch File to Prevent a Source File from Being Imported Based on Date Stamp | 30 | 118 | |

exchange 2007, active directory | 5 | 60 | |

Powershell Find Folders | 7 | 43 | |

Google (Get Users Email) | 2 | 19 |

Join the community of 500,000 technology professionals and ask your questions.

Connect with top rated Experts

**14** Experts available now in Live!