This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Published on

13,298 Points

A common challenge, or question, when working with two calendar dates is:

*What is the difference between the specified days?*

As is frequently the case, the answer is: It depends...

*What kind of difference do you want?*

Given two date objects, you can simply subtract one from the other to get a difference.

This causes us to ask:*What does the displayed value (283824002000) represent?*

It's the number of milliseconds between the specified dates & times.

*Is there an easy way to convert this into something useable?*

Sure. This works reasonably well:

**Technique #1**

Wait a minute... (pun intended) This does provide an accurate difference, but it really isn't the kind of value that people expect. If you use this code to display the difference between 1/28/2009 and 2/28/2009, the result is "31 days". Although accurate, this is not always pleasing to people, who might be expecting something like "1 month".

*Can we expand this simple loop to include the calculation of the difference in months?* Well, the answer to that question is "not without a bit more work". *Why not?* Because the length of each month is not a fixed value, that's why.

*So, how do we compute a difference between two dates that takes months into consideration?* Conceptually, this is pretty straight-forward:

+Compute the difference for each of the following parts of the two dates:

- Years

- Months

- Days

- Hours

- Minutes

- Seconds

+Then, check these differences (bottom to top), looking for negative values. When you find a negative value:

- decrement the next larger units

- add "the appropriate amount" to the current value.

The biggest question is:*What is the "appropriate value" for the number of days in a month?*

Again the answer is: it depends...

*How do we compute the "appropriate" number of days for the month?*

Again, we can make use of a really nice property of the JavaScript date object. That is, if you construct a Date object with the "day of the month" as 0, the result will be the last day of the preceding month. For example, to create a new Date object to display the last day in February of 2009, you could simply:

Note: the parameters for the date constructor are:

- The full (4 digit) year

- The ordinal month number (where Jan = 0, Feb = 1, ... and Dec = 11)

- The date of the month

So, the date value being constructed is for the 0th day of the 3rd month (March), which is interpreted as the last day of the 2nd month (February), and the result will be a date object for: Sat Feb 28, 2009

*So, how do we use this in our script?*

**Technique #2**

Before adjusting the values, the original contents of the 'diff' array were [ 32,-9,-27,-11,-59,-58 ].

After adjusting the values, we have [ 31,2,0,12,0,2 ] (i.e., 31 years, 2 months, 12 hours, and 2 seconds).

This looks reasonable, but if we compare the output of the two techniques, we find that the result of the first technique shows that the difference between "Dec 29, 1977 23:59:58" and "Mar 2, 2009 12:00:00" is:

So technique #1 has 70 days, and technique #2 has 2 months. Wait a minute. The longest month of the year has 31 days. So two months has to be less than 63 days.*Why is there a difference between these two techniques?*

Take a look at the difference in years. Over a 31 year span, how many leap years do you think there are? That's where the difference exists.*How do we determine the number of leap days that exist between two dates?*

First, we need an easy way to determine whether or not a specific year is a leap year. We could use one of the readily available expressions, or we could let the JavaScript date object do it for us. For example:

This simply tries to create a date object for Feb 29 of a specified year. If the result isn't on the 29th, then it isn't a leap year, and the function returns false.

So, to determine the number of leap days between two particular days, we need something like this, which handles the starting and ending dates differently.

**Computing the number of Leap Days**

So adding the above to the calculations found in technique #2, we find that 8 leap days exist between the two dates. So, the total difference, as calculated by technique #2 is:

Sample pages are available below.

Technique-1.html.txt

Technique-2.html.txt

Technique-2b.html.txt

Hopefully you find this article, and these samples helpful...

As is frequently the case, the answer is: It depends...

Given two date objects, you can simply subtract one from the other to get a difference.

```
var day1 = new Date( '2/29/2000 23:59:58' );
var day2 = new Date( 'Feb 27, 2009 00:00:00' );
alert( day2 - day1 )
```

This causes us to ask:

It's the number of milliseconds between the specified dates & times.

Sure. This works reasonably well:

```
var day1 = new Date( '2/29/2000 23:59:58' );
var day2 = new Date( 'Feb 27, 2009 00:00:00' );
var units = 'Years,Days,Hours,Minutes,Seconds'.split( ',' );
var vals = [ 365 * 24 * 60 * 60, 24 * 60 * 60, 60 * 60, 60 ];
var msg = '';
var secs = Math.abs( Math.floor( ( day2 - day1 ) / 1000 ) );
for ( var i = 0; i < vals.length; i++ ) {
var result = Math.floor( secs / vals[ i ] );
if ( result ) {
msg += '\n' + units[ i ] + ' ' + result;
}
secs -= result * vals[ i ];
}
if ( secs ) {
msg += '\n' + units[ i ] + ' ' + secs;
}
alert( msg.substr( 1 ) );
```

Wait a minute... (pun intended) This does provide an accurate difference, but it really isn't the kind of value that people expect. If you use this code to display the difference between 1/28/2009 and 2/28/2009, the result is "31 days". Although accurate, this is not always pleasing to people, who might be expecting something like "1 month".

+Compute the difference for each of the following parts of the two dates:

- Years

- Months

- Days

- Hours

- Minutes

- Seconds

+Then, check these differences (bottom to top), looking for negative values. When you find a negative value:

- decrement the next larger units

- add "the appropriate amount" to the current value.

The biggest question is:

Again the answer is: it depends...

Again, we can make use of a really nice property of the JavaScript date object. That is, if you construct a Date object with the "day of the month" as 0, the result will be the last day of the preceding month. For example, to create a new Date object to display the last day in February of 2009, you could simply:

```
alert( new Date( 2009, 2, 0 ) );
```

Note: the parameters for the date constructor are:

- The full (4 digit) year

- The ordinal month number (where Jan = 0, Feb = 1, ... and Dec = 11)

- The date of the month

So, the date value being constructed is for the 0th day of the 3rd month (March), which is interpreted as the last day of the 2nd month (February), and the result will be a date object for: Sat Feb 28, 2009

```
var day1 = new Date( 'Dec 29, 1977 23:59:58' );
var day2 = new Date( 'Mar 2, 2009 12:00:00' );
var diff = [
day2.getFullYear() - day1.getFullYear(),
day2.getMonth() - day1.getMonth(),
day2.getDate() - day1.getDate(),
day2.getHours() - day1.getHours(),
day2.getMinutes() - day1.getMinutes(),
day2.getSeconds() - day1.getSeconds()
];
var delta = [ 12, 31, 24, 60, 60 ];
delta[ 1 ] = ( new Date( day2.getFullYear(), day2.getMonth(), 0 ) ).getDate();
for ( var i = diff.length - 1; i > -1; i-- ) {
if ( diff[ i ] < 0 ) {
if ( i > -1 ) {
var j = i - 1;
diff[ i ] += delta[ j ];
diff[ j ]--;
} else {
alert( 'Negative year difference: ' + diff[ 0 ] );
}
}
}
```

Before adjusting the values, the original contents of the 'diff' array were [ 32,-9,-27,-11,-59,-58 ].

After adjusting the values, we have [ 31,2,0,12,0,2 ] (i.e., 31 years, 2 months, 12 hours, and 2 seconds).

This looks reasonable, but if we compare the output of the two techniques, we find that the result of the first technique shows that the difference between "Dec 29, 1977 23:59:58" and "Mar 2, 2009 12:00:00" is:

```
Difference = 31 Years 70 Days 12 Hours 2 Seconds
```

So technique #1 has 70 days, and technique #2 has 2 months. Wait a minute. The longest month of the year has 31 days. So two months has to be less than 63 days.

Take a look at the difference in years. Over a 31 year span, how many leap years do you think there are? That's where the difference exists.

First, we need an easy way to determine whether or not a specific year is a leap year. We could use one of the readily available expressions, or we could let the JavaScript date object do it for us. For example:

```
function isLeapYear( y ) {
return ( new Date( y, 1, 29 ).getDate() == 29 );
}
```

This simply tries to create a date object for Feb 29 of a specified year. If the result isn't on the 29th, then it isn't a leap year, and the function returns false.

So, to determine the number of leap days between two particular days, we need something like this, which handles the starting and ending dates differently.

```
var leapdays = 0;
if ( ( day1.getMonth() < 2 ) && ( day1.getDate() < 29 ) ) {
if ( isLeapYear( day1.getFullYear() ) ) {
leapdays++;
}
}
for ( var year = day1.getFullYear() + 1; year < day2.getFullYear(); year++ ) {
if ( isLeapYear( year ) ) {
leapdays++;
}
}
if ( isLeapYear( day2.getFullYear() ) && ( ( day2.getMonth() > 1 ) || ( ( day2.getMonth() == 1 ) && ( day2.getDate() > 28 ) ) ) ) {
leapdays++;
}
```

So adding the above to the calculations found in technique #2, we find that 8 leap days exist between the two dates. So, the total difference, as calculated by technique #2 is:

```
Years: 31
Months: 2
Days : 0
Hours: 12
Minutes: 0
Seconds : 2
Leap Days: 8
```

Sample pages are available below.

Technique-1.html.txt

Technique-2.html.txt

Technique-2b.html.txt

Hopefully you find this article, and these samples helpful...

4 Comments

var date = new Date(2009,11,1,0,0,0); // months start at 0

And before you compare dates like

var today = new Date(); // today

var someDate(2009,11,2);

you should normalise such dates by doing

today.setHours(0,0,0,0); // set hours, minutes, seconds and milliseconds to 0

so you can test

if (someDate.getTime() > today.getTime()) ....

Next Article:Understanding JavaScript part - 1 (getting started)