reptile7's JavaScript blog
Thursday, February 18, 2010
 
The Date Object and Its Discontents
Blog Entry #171

HTML Goodies' "Beyond HTML : JavaScript" portal page links not once but twice to a "JavaScript Date/Time Methods" series of four tutorials authored by Vince Barnes. A slog through the Internet Archive's HTML Goodies timeline suggests that the "JavaScript Date/Time Methods" series was written in early 2005, well after the late-1990s period during which Joe Burns wrote HTML Goodies' original JavaScript Primers and Script Tips. At no point in the "JavaScript Date/Time Methods" tutorials does Vince link to any of Joe's earlier JavaScript materials dealing with the core JavaScript Date object - he could have at least linked to JavaScript Primers #3, for example. Vince doesn't link to any of Netscape's materials either, but of course, it's the exception rather than the rule when anybody links to the 'primary literature' in the Web coding world.

The "JavaScript Date/Time Methods" series is described as follows:
This HTML Goodies series shows how to use some of the more important Date and Time tools for Web Developers. Server Side and Client Side tools are discussed, along with some special considerations for the Web. Step through this mini-series to learn about the available tools and to develop yourself into a globally thinking citizen of the World Wide Web!
The series doesn't live up to the above hype, I'm sorry to report. The series tutorials present some basic information and two small scripts that illustrate only a handful of the Date object's 50+ methods. And whereas the spotlighted methods all appear in the Server-Side JavaScript 1.2 Reference's Date object documentation, and thus can be considered "server-side tools", there's nothing particular to server-side JavaScript in the series tutorials. As for special considerations for the Web, the series' first two tutorials sport some meandering discussion in this regard but that's about it.

Nonetheless, there's no reason why we can't take a quick look at what's going on in the "JavaScript Date/Time Methods" tutorials, why not? The organization of the series material leaves room for improvement. The first tutorial in the series, "What's The Time? Using JavaScript to Localize Time Displays", should really be the last of the lot, and we'll begin our tour of the series with its second and more basic tutorial, "The Date( ) Object".

Surveying the Date landscape

"The Date( ) Object" introduces the core JavaScript Date object, shows how to create Date object instances, and briefly discusses the information that is contained in an individual Date object.

Instantiation notes

• It's not necessary to variabilize a new Date object if you're only going to use it in one command; for example,

document.write("The current date and time is: " + new Date( ).toLocaleString( ));
/* Putting a semicolon immediately after toLocaleString( ) (i.e., before the right parenthesis of the document.write( ) command) will throw an error. */


outputs (outputted when I ran it)

The current date and time is: February 12, 2010 4:13:38 PM CST

without the need for a variable.

• In saying that a Date object can [have] any variable name you wish, Vince should more specifically state that a variable for a Date object (or for any other expression) can't be a JavaScript reserved word and must otherwise conform to JavaScript's rules for naming variables.

"The Date( ) Object" also features a mostly complete list of methods of the Date object. This list is missing the following methods:
now( ), toDateString( ), toLocaleDateString( ), toLocaleFormat( ), toLocaleTimeString( ), toSource( ), and toTimeString( ).
(I myself am leaving out here those Date object methods that are inherited from the core Object and Function objects.)
Two of the methods on Vince's list, setDay( ) and setUTCDay( ), are in fact NOT JavaScript Date object methods. Netscape tersely comments here on why the Date object does not have a setDay( ) method: There is a getDay( ) method that returns the day of the week, but no corresponding setDay( ) method, because the day of the week is set automatically.

For a full list of JavaScript Date object methods, see the current Date object page in the Core JavaScript 1.5 Reference.

Vince correctly notes that the getYear( ) and setYear( ) methods are deprecated. As of this writing, the toGMTString( ) method is also deprecated - we'll have more to say about this method later.

Vince is moreover right to single out the static parse( ) and UTC( ) methods, but these methods do not belong or have any relation to the Date constructor. The parse( ) and UTC( ) methods are not methods of Date object instances, they don't act on Date objects, they don't create Date objects, and they don't return Date objects. They do respectively act on string and number data corresponding to Date objects and then return millisecond values again corresponding to those objects. For example:

var ms40years = Date.UTC(2010, 0, 1, 0, 0, 0, 0);
/* ms40years returns 1262304000000, the number of milliseconds between January 1, 1970, 00:00:00 UTC and January 1, 2010, 00:00:00 UTC. */


JavaScript 1.5 introduced a third static Date method, now( ), which returns the milliseconds elapsed since 1 January 1970 00:00:00 UTC up until now as a number, quoting Mozilla. Of the OS X GUI browsers on my computer, the now( ) method is supported by Camino, Chrome, Firefox, and Safari, but is not supported by MSIE or Opera.
(In its now( ) description, Mozilla links the word number to its page for the core JavaScript Number object. FYI, typeof Date.now( ) returns number and not object.)

Lastly, whereas a Date object's fields are indeed accessed via its methods, it is not true that [t]he Date( ) object doesn't have properties that can be directly read and written. As you can see from the aforelinked Mozilla Date object page, the Date object does have a small collection of properties, the majority of which are inherited from the core Function object and most of which are read-only. These properties and their returns are not relevant to our present discussion, however.

The methods listed in "The Date( ) Object" are relisted in a somewhat more organized way and with a bit of elaboration in the third and fourth series tutorials, which are both titled "Using Date( ) Object Methods".

Before moving on, I want to comment on something in Vince's "Date Object( )" introduction that I find historically odd:
With all these time zone issues, formatting problems and mathematical nightmares, web programmers all over the world would spend hour after hour writing code to handle the variety of situations their page might have to contend with unless somebody did something to help them out.

They did.

Included in JavaScript is a Date Object. This object is a part of the overall specification of JavaScript and is available to any page that can include JavaScript (these days, that pretty much means any page.)
The JavaScript Date object, which to my understanding was patterned on the standard Java Date class, was implemented in JavaScript 1.0, the very first version of JavaScript. As public specifications, both Java and JavaScript made their debuts in the first half of 1996 and thus between the W3C's approvals of HTML 2.0 (September 22, 1995) and HTML 3.2 (January 14, 1997). Web coders can incorporate dynamic date/time content into an HTML page via
(a) the applet element, which was implemented in HTML 3.2 but is now deprecated,
(b) the script element, which was also implemented (if in a very cursory way) in HTML 3.2, and
(c) the object element, which was introduced in HTML 4.
So I fail to see how Web coders could have spent hour after hour writing [date/time] code prior to 1996 because they simply didn't have any HTML tools enabling them to do so back then. (I admit I am not conversant with date/time programming for the Internet in the pre-Web days.)

Another dayspan calculator

There's no real code to speak of in either "The Date( ) Object" or the fourth-in-the-series "Using Date( ) Object Methods" tutorial, but the third-in-the-series "Using Date( ) Object Methods" tutorial concludes with a short script that calculates the number of days spanning two Date objects:

<script type="text/javascript">

today = new Date( ); // set today's date
birthday = new Date( ); // set up the Birthday object

birthday.setMonth(11); // set birthday month to December
birthday.setDate(15); // set birthday date to the 15th

if (today.getTime( ) < birthday.getTime( )) {
diff = birthday.getTime( ) - today.getTime( );
diff = Math.floor(diff / (1000 * 60 * 60 * 24));
document.write("There are " + diff + " days until December 15."); }

</script>


The script should really appear at the end of the fourth-in-the-series "Using Date( ) Object Methods" tutorial as that tutorial does discuss getTime( ), the (not-so-)key Date object method upon which the script relies. You might recall that we encountered a similar dayspan calculator script in Script Tips #29 and #30, which we deconstructed in Blog Entry #62.

The script specifically calculates the number of days between today, a variable holding the current day, and birthday, a variable set to December 15 of the same year.

Comments

• Per this Netscape example, it's actually not necessary to use the getTime( ) method to carry out a today vs. birthday millisecond comparison; the if declaration and the first if block statement can be written as:

if (today < birthday) {
diff = birthday - today;


• The today and birthday objects are initially created at almost the same time. After birthday is set to December 15, today and birthday have identical getHours( ), getMinutes( ), and getSeconds( ) returns, and even their getMilliseconds( ) returns are usually identical. As a result, diff = birthday - today; is an even multiple of 86,400,000 - the number of milliseconds in a day - in most runs of the script, and one is tempted to throw out the Math.floor( ) function on the following line. However, on isolated occasion, I find that the today/birthday getMilliseconds( ) returns are off by a millisecond (not more than that), so perhaps we should leave the Math.floor( ) function in place.

• After the script, Vince has an assignment for us: As an interesting exercise, try enhancing this script to determine if today is the birthday, or if this year's birthday has already passed (there's already code for that) and printing an appropriate message in each case. To handle the "today is the birthday" situation, the if statement can be rewritten as:

if (today <= birthday) {
diff = birthday - today;
diff = Math.floor(diff / (1000 * 60 * 60 * 24));
if (!diff) // If diff is 0, which converts to false in a Boolean context:
document.write("Happy Birthday!");
else document.write("There are " + diff + " days until December 15."); }


To handle the "this year's birthday has already passed" situation, we can supplement the if statement with a suitable else clause:

if (today <= birthday) { ... }
else // If today is greater than (i.e., later than) birthday:
document.write("You missed my birthday, but it's not too late to get me a nice present.");


Localize it

In general terms, "What's The Time? Using JavaScript to Localize Time Displays", the first "JavaScript Date/Time Methods" tutorial, scratches the surface of the broader issues of computing internationalization and localization, which are beyond the scope of this entry.

"What's The Time?..." concludes with a script that showcases the toLocaleString( ) Date object method and for good measure also displays returns for the getTimezoneOffset( ) and toGMTString( ) Date object methods:

<html><head></head><body><script type="text/javascript">
ourDate = new Date( );
document.write("The time and date at your computer's location is: " + ourDate.toLocaleString( ) + ".<br />");
document.write("The time zone offset between local time and GMT is " + ourDate.getTimezoneOffset( ) + " minutes.<br />");
document.write("The time and date (GMT) is: " + ourDate.toGMTString( ) + ".<br />");
</script></body></html>


Comments

• The toLocaleString( ) method converts the date to a string using the formatting convention of the operating system where the script is running, quoting Mozilla. The toLocaleString( ) return format on my computer is given in the Instantiation notes subsection above; depending on your locale, your toLocaleString( ) return, which you can check via the demo that follows the script in the tutorial, may or may not be formatted differently.

JavaScript has more specific toLocaleDateString( ) and toLocalTimeString( ) Date object methods that respectively return the date and time parts of the toLocaleString( ) return. Contra Netscape/Mozilla, the toLocaleDateString( ) and toLocaleTimeString( ) methods were not implemented in JavaScript 1.0 but in fact first appeared in JavaScript 1.5. (The aforementioned toLocaleFormat( ) method is not related to these methods. I am not inclined to discuss the toLocaleFormat( ) method as it is only supported by Firefox and Camino on my computer.)

• We previously discussed the getTimezoneOffset( ) method in Blog Entry #103 in the course of working through the "World Clock" script of Script Tips #87-90.

• Like the toLocaleString( ) method, the deprecated toGMTString( ) method returns a string giving the date and time, but in the GMT (UTC+0) time zone; toGMTString( ) has been replaced by a toUTCString( ) method giving an identical return (at least they're identical on my computer). The toGMTString( )/toUTCString( ) return is formatted a bit differently vis-à-vis the toLocaleString( ) return and, unlike the toLocaleString( ) return, also gives the day of the week as a three-letter abbreviation:

document.write(new Date( ).toUTCString( ));
// Return: Wed, 17 Feb 2010 01:01:16 GMT


Of course, the usefulness of any date/time script depends on whether or not the date and time are set correctly on the user's computer. In his "What's The Time?..." introduction, Vince notes that the date and time on a client computer can be synchronized with that of a remote server - for example, I could coordinate my computer clock with Apple's time.apple.com server - but the user doesn't have to do that, and there's nothing stopping the user from maintaining her/his computer at an incorrect date and time.
(When my old G3 iMac would hang, sometimes its clock date was reset to January 1, 1904. Upon restarting, I was prompted to reset the clock and always did so, but there was nothing forcing me to do so.)

Regarding time zones, Vince observes, Every modern operating system holds a setting that tells it where it is, or more specifically which time zone it's in, which is true -
Setting the time zone on my iMac
but there's nothing stopping the user from maintaining her/his computer at an incorrect time zone setting, either; indeed, one "What's The Time?..." commenter affirms, I have seen users who have their computers set to a different time zone than the one they are in. Also traveling with a laptop across time zones only gives you the time of the owner's home and not where the laptop is 'now'.

Regarding daylight saving time, Vince's claim that you don't have to worry about it because operating systems adjust for daylight saving times, if applicable should be generally true if you were to buy a new computer today, but what if here in the U.S. you were to buy a used, pre-2007 computer that was produced when the DST period was different? What if the government in your locale were to change the DST period in the future, or were to implement DST if it doesn't currently do so or vice versa?

Again, it is ultimately up to the user to sort out these variables - date, time, time zone, DST - in order to utilize a date/time script.

In the next few posts, we'll jazz up your forms via a tour of "JavaScript Form Scripts", another "Beyond HTML : JavaScript" series comprising four tutorials. We'll take up the first "JavaScript Form Scripts" tutorial, "Submit The Form Using Enter", in the following entry.

reptile7

Comments: Post a Comment

<< Home

Powered by Blogger

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