15.7 Displaying the Number of Days Before Christmas
NN 4, IE 4
15.7.1 Problem
You want to display the amount of
time before a known date and/or time in the user's
local time zone.
15.7.2 Solution
The following function returns the
number of days prior to the next Christmas in the
user's local time zone:
function getDaysBeforeNextXmas( ) {
var oneMinute = 60 * 1000;
var oneHour = oneMinute * 60;
var oneDay = oneHour * 24;
var today = new Date( );
var nextXmas = new Date( );
nextXmas.setMonth(11);
nextXmas.setDate(25);
if (today.getMonth( ) = = 11 && today.getDate( ) > 25) {
nextXmas.setFullYear(nextXmas.getFullYear( ) + 1);
}
var diff = nextXmas.getTime( ) - today.getTime( );
diff = Math.floor(diff/oneDay);
return diff;
}
The value returned is an integer representing days, which you can
insert into body text either while the page is loading or afterward,
as in the following:
<p>Only
<script type="text/javascript">document.write(getDaysBeforeNextXmas( ))</script>
shopping days until Christmas.</p>
15.7.3 Discussion
Approaching the "How many days
before?" problem has some side implications that you
need to address before deploying a solution. In the case of the
Solution in this recipe, the function operates year after year
without maintenance because the target date is not pegged to any
particular year. The extra if condition handles
the case when the current date is sometime after Christmas but before
January 1 of the following year. To make the calculation arrive at
the correct count, the target comparative date is pushed out to the
following year.
You could also rework the function to be more generic, whereby it
accepts parameters for a target date in the future, complete with the
year. Such a function looks like the
following:
function getDaysBefore(year, month, date) {
var oneMinute = 60 * 1000;
var oneHour = oneMinute * 60;
var oneDay = oneHour * 24;
var today = new Date( );
var targetDate = new Date( );
targetDate.setYear(year);
targetDate.setMonth(month);
targetDate.setDate(date);
alert(targetDate);
var diff = targetDate.getTime( ) - today.getTime( );
diff = Math.floor(diff/oneDay);
return diff;
}
If you are familiar with the Date object, you may
wonder why the call to the constructor function for the target date
object doesn't pass the getDaysBefore(
) arguments directly to the constructor. It is because the
value for today includes the hours and minutes into the current day.
To compare the current date against a future date,
it's important to compare the same times in the two
dates: if the target date only was handed to the constructor, the
time would be 00:00:00 on that date.
Although this example shows calculations for the number of days, you
can derive other time units by modifying the next-to-last
statement's divisor from oneDay
(for the number of days) to oneHour (for the
number of hours) or oneMinute. The date
calculations are performed at the millisecond level, so you can get
even more granular if you like.
You aren't limited to displaying the results as text
in the body content. If you have graphic images of each number from 0
through 9, you can convert the number returned into a graphical
display comprising those images. For example, if you have your images
named 0.jpg, 1.jpg, and so
on, the following function assembles the HTML for a sequence of
img elements:
function getDaysArt( ) {
var output = "";
var dayCount = getDaysBeforeNextXmas( ) + "";
for (var i = 0; i < dayCount.length; i++) {
output += "<img src='digits/" + dayCount.charAt(i) + ".jpg'";
output += "height='120' width='60' alt='" + dayCount.charAt(i) + "' />";
}
return output;
}
As the page loads, use document.write( ) to insert
this HTML where needed:
<p>Only
<script type="text/javascript">document.write(getDaysArt( ))</script>
shopping days until Christmas.</p>
15.7.4 See Also
Recipe 15.8 for a countdown timer pegged to a particular time zone in
the world; Recipe 15.9 for a calendar-based date picker.
|