[ Team LiB ] Previous Section Next Section

2.11 Calculating the Number of Days Between Two Dates

NN 2, IE 3

2.11.1 Problem

You want to find out how many days come between two known dates.

2.11.2 Solution

Use the daysBetween( ) function shown in the Discussion to obtain an integer signifying the number of whole days between two dates that are passed as parameters to the function. For example:

var projectLength = 0;
// validate form entries with checkDate( ) function from Recipe 2.12
var startField = document.entryForm.startDate;
var endField = document.entryForm.endDate;
if (checkDate(startField) && checkDate(endField)) {
    var startDate = new Date(startField.value);
    var endDate = new Date(endField.value);
    projectLength = daysBetween(startDate, endDate);
}
if (projectLength > 0) {
    alert("You\'ve specified " + projectLength + " days for this project.");
}

2.11.3 Discussion

Example 2-2 shows the daysBetween( ) utility function. The function's two arguments are date objects.

Example 2-2. daysBetween( ) function for calculating days between dates
function daysBetween(date1, date2) {
    var DSTAdjust = 0;
    // constants used for our calculations below
    oneMinute = 1000 * 60;
    var oneDay = oneMinute * 60 * 24;
    // equalize times in case date objects have them
    date1.setHours(0);
    date1.setMinutes(0);
    date1.setSeconds(0);
    date2.setHours(0);
    date2.setMinutes(0);
    date2.setSeconds(0);
    // take care of spans across Daylight Saving Time changes
    if (date2 > date1) {
        DSTAdjust = 
            (date2.getTimezoneOffset( ) - date1.getTimezoneOffset( )) * oneMinute;
    } else {
        DSTAdjust = 
            (date1.getTimezoneOffset( ) - date2.getTimezoneOffset( )) * oneMinute;    
    }
    var diff = Math.abs(date2.getTime( ) - date1.getTime( )) - DSTAdjust;
    return Math.ceil(diff/oneDay);
}

The calculation is based on the number of milliseconds between the two dates. Because it is possible that one or both of the arguments' date objects could have been created with times (as happens when invoking the Date( ) constructor method without parameters), the function sets the times of both objects to zero.

You probably noticed the code in the daysBetween( ) function that revolves around the DSTAdjust variable. This adjustment is needed when the span of time between the two dates includes a local time change�known as Daylight Saving Time in North America, and Summer Time in many other parts of the world.

While every day has a fixed number of milliseconds (as far as JavaScript is concerned), the days in which the time changes occur can have an artificial measure of 23 or 25 hours. When the function sets the hours, minutes, and seconds of the date objects to zero, the values are assigned to the local time of the client computer. Consider what happens during the change back to standard time, when the day with the change lasts for 25 hours. If that day is a Sunday, and you want to count the number of days between Friday and Monday, the total number of milliseconds between those two days will have one hour's worth of extra milliseconds in the total difference between the two dates. Without adjusting for this extra hour, the daysBetween( ) function returns an integer showing one more day than is actually there (by taking the ceiling of the result of dividing the total number of elapsed milliseconds by the number of milliseconds in one day).

It's almost magic that the date management mechanism of the JavaScript interpreter (working in concert with the operating system) knows that for a given locale (as determined by the operating system), the offset from GMT is one measure during Daylight Saving Time and another measure during standard time. It is that intelligent offset measure that the daysBetween( ) function uses to determine the amount of adjustment to make to the calculation. For a date span that does not cross one of these boundary cases, the value of DSTAdjust is zero; but during those breaks, the variable holds the number of minutes difference between the two dates (the getTimezoneOffset( ) method returns a value in minutes).

2.11.4 See Also

Recipe 15.7 for a dynamic display of the number of shopping days until Christmas; Recipe 15.8 for a dynamic count-down timer.

    [ Team LiB ] Previous Section Next Section