reptile7's JavaScript blog
Sunday, March 23, 2014
 
Holiday Like It's 1999
Blog Entry #313

In today's post we will take up the "Post Next Holiday" script in the Scripts that Display Text section of the Java Goodies JavaScript Repository. Authored by Brian Pomeroy in late 1998, the Post Next Holiday script determines the holiday that most closely follows the current date and prints out a "Next holiday is …" message.

The Post Next Holiday script was formerly posted at www.javagoodies.com/postnextholiday.txt, but this page is now gone; fortunately, Joe Burns' online JavaScript Goodies book hosts the script here. The script's demo would work - you'd see the aforementioned message just below the "Place on your employee intranet …" paragraph - if it were 1999 or earlier, but it isn't.

The holiday landscape

Here in the U.S. there are 10 annual federal holidays. The Post Next Holiday script takes in seven of those holidays:
(1) New Year's Day
(2) Birthday of Martin Luther King, Jr.
(4) Memorial Day
(5) Independence Day
(6) Labor Day
(9) Thanksgiving
(10) Christmas
Not taken into account are:
(3) Washington's Birthday
(7) Columbus Day
(8) Veterans Day

The quadrennial Inauguration Day is also a federal holiday, or at least it is for Washington, D.C., and nearby parts of Maryland and Virginia.

Script content

In this section we will deconstruct the Post Next Holiday script per its original code; subsequently we will unfix the script from its 1999 mooring and bring the omitted holidays into the mix.

The script begins by creating Date objects for the current date and for the 1999 aforenoted holidays:

today = new Date( );
newyear = new Date("January 1, 1999");
mlkday = new Date("January 18, 1999");
memday = new Date("May 31, 1999");
indday = new Date("July 5, 1999");
labor = new Date("September 6, 1999");
thanksgiving = new Date("November 25, 1999");
christmas = new Date("December 24, 1999");


• Excepting May, the month parts of the dateString Date constructor arguments do not but should conform with the three-letter values of the month-name production in RFC 2822: January should be specified as Jan, July should be Jul, etc. For more on acceptable dateString arguments, see Mozilla's page on the parse( ) method of the Date object.

• The 1999 holiday dates can be verified by running cal 1999 on the command line - no need to go running to Wikipedia's 1999 pages.

• In 1999, July 4 was a Sunday and December 25 was a Saturday; the corresponding Independence Day and Christmas holidays were consequently observed on July 5 and December 24, respectively.

The Date constructor statements are followed by a set of if statements that determines where the today date falls relative to the newyear-christmas holidays:

if (today <= newyear) { holiday = "New Year's Day (Jan. 1)"; }
if ((today <= mlkday) && (today > newyear)) { holiday = "Martin Luther King's Birthday (Jan. 18)"; }
if ((today <= memday) && (today > mlkday)) { holiday = "Memorial Day (May 31)"; }
if ((today <= indday) && (today > memday)) { holiday = "Independence Day (July 5)"; }
if ((today <= labor) && (today > indday)) { holiday = "Labor Day (Sept. 6)"; }
if ((today <= thanksgiving) && (today > labor)) { holiday = "Thanksgiving Day (Nov. 25)"; }
if ((today <= christmas) && (today > thanksgiving)) { holiday = "Christmas Day (Dec. 24)"; }


If today precedes or is the newyear holiday, then a New Year's Day (Jan. 1) string is assigned to a holiday variable, meaning the next holiday is New Year's Day; if today precedes or is the mlkday holiday AND if today follows the newyear holiday, then the next holiday is Martin Luther King's Birthday (Jan. 18); and so on.

We can directly compare the various Date objects with comparison operators because a JavaScript Date object represents a single moment in time [relative to midnight] 1 January, 1970 UTC. The inner parentheses surrounding each comparison subcondition are unnecessary as comparison operators take precedence over the logical && (AND) operator, but there's no harm in holding onto them if you feel that they improve the code's readability.

A holiday message is written to the page by a separate if statement:

if (document.write) { document.write("<b>Next holiday is " + holiday + "</b>"); }

I've looked at my share of prehistoric JavaScript code and I have to say that this is the first time I've seen a document.write if gate. Such conditionalization is unnecessary as the write( ) method of the document object goes all the way back to JavaScript 1.0, the very first version of JavaScript: a browser that doesn't recognize document.write is a browser that won't know what to do with JavaScript in the first place.

The current versions of IE and Netscape in 1998 were IE 4.x and Netscape 4.x, respectively. Evidently the document.write( ) command was for the benefit of Netscape users; IE users could have written the holiday message to the innerHTML of a document.all("elementID") element. BTW, the </b> tag's </ character sequence is illegal, and should be escaped with a backslash (i.e., <\/b>).

Its 1999 dates notwithstanding, you can try out the original Post Next Holiday script by inputting a 1999 dateString into the today constructor: for example, a today = new Date("Mar 21, 1999"); starting point smoothly outputs a Next holiday is Memorial Day (May 31) holiday message.

Now, we could update the script by simply changing its various Date dateStrings and holiday strings - go here for an official list of 2014 federal holidays - but this is setting the bar rather low. Clearly, a better course of action would be to craft a more general script that tracks holidays not just for 2014 but for subsequent years as well, and we'll do just that in the next post.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)