Tuesday, December 03, 2013
The Christmas Countdown
Blog Entry #308
The "Days Until Christmas" script's demo page is here; the days number is wildly off for reasons we will discuss below.
(Mozilla's Date object page provides links to separate pages for the getTime( ), getYear( ), setYear( ), getFullYear( ), and setFullYear( ) methods that are mentioned in this section.)
The "Days Until Christmas" script is a short one so let me give it to you in one go:
Did you know that there's
today = new Date( );
xmas = new Date("December 25, 1997");
xmas.setYear = today.getYear;
daysLeft = (xmas.getTime( ) - today.getTime( )) / (1000 * 60 * 60 * 24);
daysLeft = Math.round(daysLeft);
document.write("only " + daysLeft + " days left until Christmas");
(1) Separate Date objects
(a) for right this moment and
(b) for 12 AM Christmas 1997
are created and respectively assigned to today and xmas variables.
(2) The xmas year is set to the today year. (We wouldn't want to be stuck in 1997, would we?)
(3) The xmas and today getTime( ) returns are subtracted to give the number of milliseconds spanning xmas and today; the milliseconds span is divided by the number of milliseconds in a day to give the number of days spanning xmas and today; the days span is assigned to a daysLeft variable.
(4) daysLeft is rounded up or down to the nearest integer by the Math object's round( ) method.
(5) The integerized daysLeft is concatenated with
" days left until Christmas"strings and the resulting string is appended to some pre-
<script>text to give the complete Christmas countdown message.
The small stuff
• The script element does not have a name attribute; a
December 25, 1997dateString argument should be specified as
Dec 25, 1997- see this section of RFC 2822.
• We don't need to reach for the getTime( ) method to determine the number of milliseconds spanning xmas and today: a simple
xmas - todaysubtraction will suffice.
• If you want the daysLeft span to always include the current day - I want the daysLeft span to always include the current day - then you should not Math.round( ) daysLeft but instead 'ceil' it with a
xmas.setYear = today.getYear;line that throws a spanner into the works, however; this statement is problematic for two reasons:
(A) It does not actually copy the today year to xmas.
(B) It attempts to make use of the
deprecated(read: obsolete) getYear( ) and setYear( ) methods, which are not suited for comparing a pre-2000 Date with a post-2000 Date.
Although it is true that a method is ultimately a property of the object with which it is associated, the
today.getYearexpression does not evaluate to the
today.getYear( )return and the
xmas.setYear = today.getYear;assignment has no effect on the
xmas.getYear( )return; as a result, the original script was really only good for 1997. (This is not to say that the script 'doesn't work' for other years, it just won't give the daysLeft value that you want it to.) For what Jari was trying to do, the correct syntax is:
The preceding command would have been OK for 1998 and 1999 but for 2000 and beyond we'll need to use the getFullYear( ) and setFullYear( ) methods instead:
The last six days of the year
Now, what if Christmas has just passed and we're in the 26 December-to-31 December period and we want to know how many days there are before the next Christmas? The above getFullYear( )/setFullYear( ) command places xmas at this year's Christmas; subsequently we can push xmas to next year's Christmas via the following conditional:
if (today > xmas) xmas.setFullYear(today.getFullYear( ) + 1);
The 24th of December
And what if it's 24 December and you would like the script to print out "1 day" as opposed to "1 days"? Why, I think we can arrange that:
var plur_or_sing = daysLeft != 1 ? " days " : " day ";
document.write("only " + daysLeft + plur_or_sing + "left until Christmas?");
Demo notesPer the More structure section of the previous post, the demo's countdown message is written to the page by assigning it to the innerHTML property of an
In place of the xmas Date I use a thisyearXmas Date that has today's year from the get-go:
var thisyearXmas = new Date(today.getFullYear( ), 11, 25);