reptile7's JavaScript blog
Saturday, February 23, 2019
 
Times of Our World, Part 2
Blog Entry #394

Let's get back now to our discussion of the Java/JavaScript Goodies World Clock -- Daylight Savings Time. In the previous entry we ticked through the dstclock clock's foundational JavaScript, preceding metatext, and HTML scaffolding; in today's post we'll unwind the clock's day and time displays. Three Clock origin values are relevant to those displays:
(w) the week string,
(h) the hour number, and
(m) the min string.

Day prep

The week string contains a three-letter day-of-the-week abbreviation plus a comma:
Sun, or Mon, or ... Sat,

The week day is the day in London. If it's Sunday in London, then it could be Monday in Sydney or Saturday in San Francisco, so we'll need to determine the week + 1 and week - 1 days in addition to the week day. Toward this end, Stuart initially maps the week value to an index number that's one higher than the corresponding getDay( ) index:

if (week == "Sun,") { week = 1; }
if (week == "Mon,") { week = 2; }
if (week == "Tue,") { week = 3; }
if (week == "Wed,") { week = 4; }
if (week == "Thu,") { week = 5; }
if (week == "Fri,") { week = 6; }
if (week == "Sat,") { week = 7; }


The week index is subsequently lowered by one for those users who are using a Macintosh:

// Fix Mac version Communicator bug
function checkOS( ) {
    if (navigator.appVersion.indexOf("Mac") > 0) return "Macintosh";
    else return "other"; }
var check = checkOS( );
if (check == "Macintosh") { week -= 1; }


• If there's a reason to use this code rather than just an
if (navigator.appVersion.indexOf("Mac") > 0) week -= 1;
statement, I don't see it.

• I myself would have reached for the navigator object's platform property to flag Macintosh users (not that we want to be 'platform sniffing' if we can help it, of course) although it is clear from JavaScript Kit's Navigator Object page - see its Additional browsers' Navigator Information subsection - that a navigator.appVersion probe will do the job.

There's no mention of any Macintosh support issues in the toGMTString( ) entry in the JavaScript 1.2 Reference. As Netscape's Communicator/Navigator 4.0-4.05 browsers have a JavaScript 1.2 engine, I downloaded Navigator 4.05 for the Macintosh from OldVersion.com and ran a
window.alert((new Date(2019, 2, 1)).toGMTString( ).split(" ")[0]);
command with it, and the alert( ) box that popped up had a Sat, on it even though 1 March 2019 is a Friday, so there you have it.

We're almost ready to start writing out the locale displays: the missing link between
the full day names in those displays and
the week index
is a weekly Array whose creation follows the checkOS( ) check.

weekly = new Array("Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");

(Nine elements? Duplicate Saturday and Sunday values? We'll clean this up later.)

More yesteryear matters, in the name of completeness

In his authorship comment, Stuart states that the dstclock code only works with Communicator 4, but should be gracefully ignored by lesser browsers. Actually, there are no features in the dstclock code that are specific to JavaScript 1.2, and I find that
if the week string → index number conversions are formulated as an if ... else if ... else if ... chain
AND
if the script language="javascript1.2" attributes are converted to language="javascript" attributes
then Navigator 3.04, which has a JavaScript 1.1 engine, runs the code without incident.

A bit of sleuthing, with some help from this Netscape onError example, revealed that Navigator 3.04 can't handle the original code for an unexpected reason: once an index number is assigned to week, the subsequent (elseless)
if (week == "Three-letter-day-of-the-week-abbreviation,") comparison
throws a "[day] is not a number" type-conversion error that propagates through the rest of the <script>. If the date object's day is a Friday, then no errors are thrown because the final
if (week == "Sat,") week = 7;
conditional is operative, as it would be for Navigator 4.05 (vide supra).

As it happens, however, Navigator 4.05 and Navigator 3.04 have another toGMTString( ) problem besides the dayday + 1 problem: the time part of the toGMTString( ) return gives the local time and not the time in London, or at least that's what I see in the SheepShaver environment on my computer, for example, for my California locale (GMT - 8)
(new Date(2019, 2, 1)).toGMTString( )
returns
Sat, 02 Mar 2019 00:00:00 GMT
rather than
Fri, 01 Mar 2019 08:00:00 GMT.

Anyway, it's not worth my while (or your while, or anyone else's while) to determine whether the time discrepancy is a browser bug or a SheepShaver artifact in that we've spent enough time with these ancient browsers as it is and we really ought to be leaving them behind, yes? We assume the use of a current browser in the following sections.

If you're going to San Francisco

The day and time display show is ready to hit the road. Here's what we've got for San Francisco:

// In the dstclock head
var sf_hour = hour - 8;
var sf_week = week;
var sf_ampm = " a.m.";
if (sf_hour < 0) {
    sf_hour += 24;
    sf_week -= 1; }
if (sf_hour > 11) { sf_ampm = " p.m."; }
if (sf_hour > 12) { sf_hour -= 12; }
if (sf_hour == 0) { sf_hour = 12; }

<!-- In the dstclock body -->
<td align="center" valign="top"><script language="javascript1.2"><!-- Hide it
document.write("<b>San Francisco</b><br>");
document.write(weekly[sf_week] + "<br>");
document.write(sf_hour + ":" + min + sf_ampm + "<br>");
// --></script></td>


The var sf_hour = hour - 8; line subtracts 8 from the hour in London to give the sf_hour in San Francisco for standard time, but there's no - 7 subtraction for daylight saving time, which is a pretty serious omission given that DST lasts more than half the year.

The var sf_week = week; line gives San Francisco the same day index that London has. If the London hour is in the 0-7 range, then San Francisco will calendar-wise be a day behind London: in this situation
(h) the hour - 8 subtraction gives a negative sf_hour, which is converted to the corresponding 12-hour clock hour by + 24 and - 12 operations, and
(w) the sf_week index is pushed back by one.
The GMT-pegged sf_week is then plugged into the weekly[ ] Array to get the full day name of the display.

An appropriate a.m./p.m. indicator is derived from the sf_hour and assigned to an sf_ampm variable à la the metatext code; moreover, the sf_hour is set to 12 for the midnight to 1 a.m. hour this time.

The day and time, plus a <br> line break that separates them, are written to the San Francisco table cell via separate document.write( ) commands (the concluding <br> in the second write( ) command serves no purpose and can be removed); we'll replace those commands with a tdObject.innerHTML += localeString assignment in due course.

For the last eight hours of Saturday the weekly[sf_week] day is undefined for Mac users as
the initial week index is decreased from 1 for Sunday in London to 0 by the checkOS( ) check and
the initial sf_week index is decreased from 0 to -1 by the if (sf_hour < 0) { ... sf_week -= 1; } conditional;
commenting out the checkOS( ) check changes the undefined to the Saturday we want.
Heading east we've got some serious redundancy on our hands: the dstclock source contains
separate units of code for Denver, Memphis, and New York that
have different hour - x GMT offsets
and of course different variable names (den_hour, mem_hour, etc.)
but are otherwise identical to the above San Francisco code
followed by separate units of code for London, Paris, Moscow, Bangkok, Tokyo, and Sydney that are only slightly more different...
We'll consolidate the lot of it, and sort out the DST thing, in the next post.

Comments: Post a Comment

<< Home

Powered by Blogger

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