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.
|