Dave Eisenberg's calendar (http://www.best.com/~nessus/js-today.html) is a good example of the use of expressions and variables, as well as
functions and objects. The program generates a dynamic Web page that includes a greeting suited to the time of day (such as "Good Evening!"), the time of day, and the current month's calendar with the current date highlighted.
In addition, the page includes an image suited to the current time of day.
In doing this, Eisenberg makes use of several techniques that we haven't seen yet. His script uses the Date object, as well as several new methods including Math.floor() from the Math object and others from the Date object.
The source code for the page is in Listing W1.1.
Input
<HTML> <HEAD> <TITLE>Greetings from Dave Eisenberg</TITLE> </HEAD> <BODY> <SCRIPT LANGUAGE="JavaScript"> <!-- to hide script contents from old browsers function greeting() { var today = new Date(); var hrs = today.getHours(); document.writeln("<CENTER>"); if ((hrs >=6) && (hrs <=18)) { document.writeln("<IMG SRC=\"daypix/day"); document.write(Math.floor(hrs / 10)); document.write(Math.floor(hrs % 10)); document.write("00.gif\">"); } else document.write("<IMG SRC=\"daypix/night1.gif\">"); document.writeln("<BR>"); document.write("<H1>Good "); if (hrs < 6) document.write("(Early) Morning"); else if (hrs < 12) document.write("Morning"); else if (hrs <= 18) document.write("Afternoon"); else document.write("Evening"); document.writeln("!</H1>"); document.write("You entered this page at "); dayStr = today.toLocaleString(); i = dayStr.indexOf(' '); n = dayStr.length; document.write(dayStr.substring(i+1, n)); document.writeln("</CENTER>"); } function montharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) { this[0] = m0; this[1] = m1; this[2] = m2; this[3] = m3; this[4] = m4; this[5] = m5; this[6] = m6; this[7] = m7; this[8] = m8; this[9] = m9; this[10] = m10; this[11] = m11; } function calendar() { var monthNames = "JanFebMarAprMayJunJulAugSepOctNovDec"; var today = new Date(); var thisDay; var monthDays = new montharr(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); year = today.getYear() + 1900; thisDay = today.getDate(); // do the classic leap year calculation if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) monthDays[1] = 29; // figure out how many days this month will have... nDays = monthDays[today.getMonth()]; // and go back to the first day of the month... firstDay = today; firstDay.setDate(1); // and figure out which day of the week it hits... startDay = firstDay.getDay(); document.writeln("<CENTER>"); document.write("<TABLE BORDER>"); document.write("<TR><TH COLSPAN=7>"); document.write(monthNames.substring(today.getMonth() * 3, (today.getMonth() + 1) * 3)); document.write(". "); document.write(year); document.write("<TR><TH>Sun<TH>Mon<TH>Tue<TH>Wed<TH>Thu<TH>Fri<TH>Sat"); // now write the blanks at the beginning of the calendar document.write("<TR>"); column = 0; for (i=0; i<startDay; i++) { document.write("<TD>"); column++; } for (i=1; i<=nDays; i++) { document.write("<TD>"); if (i == thisDay) document.write("<FONT COLOR=\"#FF0000\">") document.write(i); if (i == thisDay) document.write("</FONT>") column++; if (column == 7) { document.write("<TR>"); // start a new row column = 0; } } document.write("</TABLE>"); document.writeln("</CENTER>"); } document.write(greeting()); document.write("<HR>"); document.write(calendar()); document.write("<HR>"); document.write("<A HREF=\"http://www.best.com/~nessus\">"); document.write("Back to Dave Eisenberg's resume<\A>"); <!-- end hiding contents from old browsers --> </SCRIPT> </BODY> </HTML>
The code produces results like those in Figures W1.1 and W1.2.
Figure W1.1. During the day time, the user gets one of several images depicting the time of day.
Figure W1.2. Using the Date object, the program builds a calendar for the current month.
End of Output
Analysis
The first thing you notice about this script is that it is not placed inside the header of the HTML file. The author does this because there is no chance of events triggering calls to functions which have not yet been defined.
In addition, all HTML code is dynamically generated by the script.
The calendar program uses three functions. The calls are made in sequence by the main body of the script:
document.write(greeting()); document.write("<HR>"); document.write(calendar()); document.write("<HR>"); document.write("<A HREF=\"http://www.best.com/~nessus\">"); document.write("Back to Dave Eisenberg's resume<\A>");
At the top of the script, two global declarations (today and hrs) occur. The command var today = new Date(); creates an instance of the system's Date object in much the same way you could create an
instance of any object you defined yourself.
The Date object enables programmers to create an object that contains information about a particular date and provides a set of methods to work with that information.
In order to create an instance of the Date object, you use the variable = new Date(parameters) form where the parameters can be any of the following:
The Date object provides the methods outlined in Table 4.1.
Name |
Description |
getDate |
Returns the day of the month as an integer from 1 to 31 |
getDay |
Returns the day of the week as an integer where zero is Sunday and one is Monday |
getHours |
Returns the hour as an integer between 0 and 23 |
getMinutes |
Returns the minutes as an integer from 0 to 59 |
getMonth |
Returns the month as an integer from 0 to 11 where zero is January and 11 is December |
getSeconds |
Returns the seconds as an integer between 0 and 59 |
getTime |
Returns the number of milliseconds since 1 January 1970 at 00:00:00 |
getTimezoneOffset |
Returns the difference between the local time and Greenwich Mean Time in minutes |
getYear |
Returns the year as a two-digit integer |
parse |
Returns the number of milliseconds since 1 January 1970 at 00:00:00 for the date string passed to it |
setDate |
Sets the day of the month based on an integer argument from 1 to 31 |
setHours |
Sets the hour based on an argument from 0 to 23 |
setMinutes |
Sets the minutes based on an argument from 0 to 59 |
setMonth |
Sets the month based on an argument from 0 to 11 |
setSeconds |
Sets the seconds based on an argument between 0 and 59 |
setTime |
Sets the time based on an argument representing the number of milliseconds since 1 January 1970 at 00:00:00 |
setYear |
Sets the year based on a four-digit integer greater than 1900 |
toString |
Returns the current date as a string |
toGMTString |
Returns the current date and time using the Internet GMT conventions (i.e. in the form "Mon, 18 Dec 1995 17:28:35 GMT") |
toLocaleString |
Returns the date as a string in the form "MM/DD/YY HH:MM:SS" |
|
|
Based on this information, the variable declaration var hrs = today=getHours() will contain the current hour when the user loads the page.
The first function the script calls is greeting(), which displays the appropriate image and welcome message along with the current time:
function greeting() { var today = new Date(); var hrs = today.getHours(); document.writeln("<CENTER>"); if ((hrs >=6) && (hrs <=18)) { document.writeln("<IMG SRC=\"daypix/day"); document.write(Math.floor(hrs / 10)); document.write(Math.floor(hrs % 10)); document.write("00.gif\">"); } else document.write("<IMG SRC=\"daypix/night1.gif\">"); document.writeln("<BR>"); document.write("<H1>Good "); if (hrs < 6) document.write("(Early) Morning"); else if (hrs < 12) document.write("Morning"); else if (hrs <= 18) document.write("Afternoon"); else document.write("Evening"); document.writeln("!</H1>"); document.write("You entered this page at "); dayStr = today.toLocaleString(); i = dayStr.indexOf(' '); n = dayStr.length; document.write(dayStr.substring(i+1, n)); document.writeln("</CENTER>"); }
The function determines that it is daytime if hrs is between 6 and 18 and then builds an image tag. The filename includes a number built up out of the hrs variable using Math.floor(). This method returns the closest integer less than the argument. In
that way, if hrs is 12, the image's filename would be day1200.gif.
The current time, which is output at the end of the function, is obtained from the string returned by the Date.toLocaleString() method. This string contains the date and time separate by a single
space. The function uses the indexOf() method of the string object. to locate the index of the space in the string. The length property of the string object is used to determine the index of the last character in the string.
The substring() method then returns the portion of the string after the index up to the end of the string. The string object, and in particular the substring() method, are discussed in more detail in later chapters. The string object is covered in depth
in Chapter 10, "Strings, Math, and the History List."
The next function to be called is the calendar() function which does the more complex job of building the calendar. The calendar is designed using HTML tables, which are discussed further in Chapter
7, "Loops."
function calendar() { var monthNames = "JanFebMarAprMayJunJulAugSepOctNovDec"; var today = new Date(); var thisDay; var monthDays = new montharr(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); year = today.getYear() + 1900; thisDay = today.getDate(); // do the classic leap year calculation if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) monthDays[1] = 29; // figure out how many days this month will have... nDays = monthDays[today.getMonth()]; // and go back to the first day of the month... firstDay = today; firstDay.setDate(1); // and figure out which day of the week it hits... startDay = firstDay.getDay(); document.writeln("<CENTER>"); document.write("<TABLE BORDER>"); document.write("<TR><TH COLSPAN=7>"); document.write(monthNames.substring(today.getMonth() * 3, (today.getMonth() + 1) * 3)); document.write(". "); document.write(year); document.write("<TR><TH>Sun<TH>Mon<TH>Tue<TH>Wed<TH>Thu<TH>Fri<TH>Sat"); // now write the blanks at the beginning of the calendar document.write("<TR>"); column = 0; for (i=0; i<startDay; i++) { document.write("<TD>"); column++; } for (i=1; i<=nDays; i++) { document.write("<TD>"); if (i == thisDay) document.write("<FONT COLOR=\"#FF0000\">") document.write(i); if (i == thisDay) document.write("</FONT>") column++; if (column == 7) { document.write("<TR>"); // start a new row column = 0; } } document.write("</TABLE>"); document.writeln("</CENTER>"); }
The function starts by defining variables which will be used later in the function, as well as defining an instance of the Date object called today and an instance of the montharr object (defined by the montharr() function) which contains 12 properties with the number of days in each month of the year.
The first step is to determine if it is a leap year so that the value of monthDays[1] (for February) can be adjusted. This is done by using today.getYear() to get the current year and then using the following if statement to
check if the year is a leap year:
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) monthDays[1] = 29;
Next, the variable nDays is assigned the number of days in the current month, The index used in monthDays is the value returned by today.getMonth() because it returns an integer which corresponds to the indexes of the monthDays object.
A copy of today called firstDay is created and the date set to the first of the month using firstDay.setDate(1) in order to figure out the day of the week using startDay = firstDay.getDay(). You could have used today.setDate(1) and today.getDay(), but
that would have made the script harder to read and understand.
The function then outputs the opening tags of the table and writes the current month out by using the substring() method on the variable monthNames. This is followed by writing the number of blank calendar spaces needed in the first row using a for
loop, which is covered in Chapter 7.
Next, another for loop is used to write out the dates of the month in sequence. The if statements with the condition (i== thisDay) are used to determine if the text color should be changed for the
current table cell.
The variable column is incremented throughout both for loops to keep track of which column of our seven-column table the current date is written into. If the date has been
written into the seventh column, then the last if statement in the second loop starts a table row with the TR tag and resets column to zero.
Finally, the function writes out all the closing HTML for the table.