reptile7's JavaScript blog
Tuesday, February 05, 2019
 
Times of Our World
Blog Entry #393

HTML Goodies' JavaScript Script Tips #87, #88, #89, and #90 discuss a world clock - see it here, get its code here - that we dissected in detail in Blog Entries #102, #103, #104, #105, and #106.

The Java/JavaScript Goodies Calculators, Calendars, and Clocks sector similarly offers a World Clock -- Daylight Savings Time, which was built by Stuart Price and which we'll take on in today's post. Stuart christened his clock WorldTime 1.0DST but I will henceforth refer to it via its dstclock document name. The dstclock clock gives static day and 12-hour time displays for ten locales:
San Francisco, Denver, Memphis, New York, London, Paris, Moscow, Bangkok, Tokyo, and Sydney.
You can see the clock at the aforelinked dstclock.html page and get its code here.

The component parts of each day and time display - the day of the week, the current hour, the current minute, and an appropriate a.m./p.m. designation - are derived from a dateObject.toGMTString( ) return, which is somewhat unusual in that most authors would use more conventional Date methods - specifically, getDay( ), getHours( )*, and getMinutes( ) - to determine those parts. In JavaScript 1.3 toGMTString( ) was deprecated in favor of a new toUTCString( ) method; toGMTString( ) and toUTCString( ) give identical returns with all of the browsers on my computer. The dstclock clock code was written in 1997 during the JavaScript 1.2 era - its various script elements hold a language="javascript1.2" attribute - when toUTCString( ) was not available.
*However, we'll call on getHours( ) when we get the user's local time in the clock preface.

In practice, the dstclock clock works OK some of the time, but it runs into trouble on Saturday or at the p.m./a.m. boundary for some locales, and it actually doesn't deal with daylight saving time at all - we'll get into all of this below.

Clock origin

Our deconstruction begins in the dstclock head this time. The ultimate starting point for every JavaScript clock is the creation of a new Date object:

<head>
<script language="javascript1.2"><!-- Hide it
/* ...Long authorship comment by Stuart... */
var date = new Date( );


The new Date is given a date identifier, which rubs me the wrong way - date is too close to Date for my taste - but is nonetheless legit as date is neither a JavaScript reserved keyword nor a JavaScript future reserved keyword.

We next obtain the toGMTString( ) form of the date Date, and assign it to a timegmt variable.

var timegmt = date.toGMTString( );

The toGMTString( ) method was actually not so well supported back in the day - more on this later - but today it reliably gives the GMT time corresponding to a time - either the current time or some other time - on the user's machine and in a regular, cross-browser format. Accordingly, if you're a user in Escondido, California and it's five in the afternoon on 1 March 2019, then the timegmt string should be:

Sat, 02 Mar 2019 01:00:00 GMT

The timegmt data is subsequently split( ) at its space-character delimiters; the resulting Array of substrings is bound to a time_string variable.

time_string = timegmt.split(" ");

The first five time_string elements are given more descriptive variable names:

week = time_string[0];
day = time_string[1];
mon = time_string[2];
year = time_string[3];
hms = time_string[4];


The hms string - the time part of the toGMTString( ) return - is then split( ) into its hour, minute, and second components, which are bound to an hms_string variable.

hms_string = hms.split(":");

We'll need an hour number to produce the UTC+x locale displays, and subtracting 0 from the hms_string[0] hour value gives us that number, which is stored in a separate hour variable. The hms_string[1] minute value is analogously stored as a string in a min variable.

var hour = hms_string[0] - 0;
var min = hms_string[1];


At a later point we'll map the week string to a getDay( )-like day-of-the-week index; no subsequent use is made of day, mon, and year.

Clock preface

The dstclock page begins with a line of metatext that
includes a local time determination and
is coded by:

<body bgcolor="#ffffff">
<script language="javascript1.2"><!-- Hide me
var loc_hour = date.getHours( );
var loc_ampm = " a.m.";
if (loc_hour > 11) { loc_ampm = " p.m."; }
if (loc_hour > 12) { loc_hour -= 12; }
document.write("<font size='2'>Note: Your local time is </font>");
document.write(loc_hour + ":" + min + loc_ampm);
document.write("<font size='2'> Times listed in the following table are based on your computer's time. If your computer's clock is wrong, so is this table.</font>");
// --></script>


You don't need a detailed play-by-play for this, do you? Didn't think so. But let me make a few points:

• Is it necessary to JavaScriptically write( ) out the non-time part of the text? Is it desirable to shrink that part of the text with the <font size="2"> ... </font> sizing? No and no.

• We can use the ?: conditional operator to set the loc_ampm setting on one line, i.e., var loc_ampm = loc_hour > 11 ? " p.m." : " a.m.";.

• For the midnight to 1 a.m. hour, adding an if (! loc_hour) loc_hour = 12; conditional will make the loc_hour hour 12 rather than 0.

• A loc_hour hour in the 0 loc_hour 9 range won't have a leading 0 because it comes from getHours( ); a min minute in the 00 min 09 range will have a leading 0 because it comes from toGMTString( ).

Clock frame

In the dstclock.txt code the clock is laid out via a one-row, ten-cell table; for the dstclock.html demo the table row is broken into three rows holding four cells, four cells, and two cells, respectively.

<table cellspacing="10">
<tr><td align="center" valign="top">
<script language="javascript1.2"><!-- Hide it
document.write("<b>San Francisco</b><br>");
document.write( /* day and time expression */ );
// --></script></td>
...
<td align="center" valign="top">
<script language="javascript1.2"><!-- Hide it
document.write("<b>Sydney</b><br>");
document.write( /* day and time expression */ );
// --></script></td></tr>
</table>


Can we alternatively use a series of display:inline-block; spans or divs for this purpose? Most certainly, but I will stick with the table in going forward.

The cellspacing attribute of the table element, the align attribute of the td element, and the valign attribute of the td element were all legit in HTML 4 but HTML 5 declares them non-conforming features that must not be used by authors.
• A cellspacing="10" interstitial separation can be achieved with a border-spacing:10px; styling.
• For the td element (and most other alignable elements) an align="center" horizontal centering maps to a text-align:center; styling.
• The ten table cells have a uniform shrink-to-fit height, and therefore the valign="top" attributes have no effect on the cell content (the default valignment is middle but there's just no room to move the content up or down in this case) and can be thrown out. However, if the height of the cell content area were measurably larger than the actual height of the content itself, then the valign="top" attributes could be replaced by a vertical-align:top; styling.

For their part, the San FranciscoSydney locale identifiers can be
written as normal text rather than scriptically and
bolded with a font-weight:bold; styling if desired.
Semantics-wise, are the identifiers heading-y enough to be marked up with one of the h# elements or are they really just label-like captions? I vote the latter and would code them as <label>s if we were loading the clock data into <input>s, although you may feel differently.
Our next task is to disconnect the nuts and bolts of the clock itself: all will be revealed in the following entry.

Comments: Post a Comment

<< Home

Powered by Blogger

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