[ Team LiB ] Previous Section Next Section

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.

    [ Team LiB ] Previous Section Next Section