This version of the clock provides support for displaying solstices and equinoxes at all levels. Where the previous version would only place solstice and equinox indicators in the year band, this one places them in every band that is relevant, such that by the time the calculated minute of one of these events arrives, there are indicators of its time shown in every band.
Implementing that support cleanly required a re-write of the Javascript that drives the clock, during which I ran headlong into a number of my misconceptions about the language. Consequently, I've learned a lot, but I've thus far entirely failed to grasp the "zen" of this language, which is frustrating. At this point, I still don't understand why anyone would design a language like Javascript.
One minor improvement in this version of the clock is a change to the definitions of the time indicator-bar symbols. (They are defined at the same size at which they appear in the clock, which means that the use elements no longer scale the bar symbols.) This change results in no visible difference, except that Safari no longer leaves behind fragments of the second hand as it moves near the 0, 90, 180 and 270 degree angles. The bug is still in Safari's SVG renderer, but, fortunately, the new bar definitions don't exercise it.
The current clock design has been extended by the inclusion of indicators for the equinoxes and solstices. The accuracy of the calculated equinox and solstice times is good - within a minute or two of the official values. Most of the error comes from having to estimate the difference between Dynamical Time (based on atomic clocks) and Universal Time (based on the slowly and unpredictably decreasing rotation of the Earth). I am indebted to Jean Meeus for his book Astronomical Algorithms which not only explains all of these matters, but offers straightforward means of computing them. (Thanks also to my colleague James Stolpa for recommending the book, and for having a copy on hand to loan to me.) Regrettably, the book is out of print, but used copies can be found. (I hope to receive my own copy soon.)
In this version of the clock, the equinox and solstice indicators are confined to the "year" band, but future versions will also show them in the month, week, hour and minute bands as the date of an equinox or solstice arrives within their scope. I hope to find time to add lunar phases after that. If there were a programmatic means of obtaining a client's latitude, I'd add sunrise and sunset indicators in a heartbeat.
Lessons Learned
When deleting items returned by the DOM element.getElementsByTagNameNS method, it is important to delete them from last-to-first. Deleting them from first-to-last produces unpredictable results - sometimes everything is deleted, sometimes only a fraction of the items are deleted.
Firefox can't handle SVG symbol elements using other symbol elements. Safari can.
Jean Meeus' book Astronomical Algorithms is wonderful. It's a shame that it's out of print.
The World Wide Web Consortium's Markup Validation Service validates SVG. You don't have to go to a special page; the validator recognizes SVG automatically and validates accordingly.
My previous SVG clock experiment merely demonstrated that Scalable Vector Graphics (SVG) could do some basic work in modern browsers like Firefox and Safari, but it didn't give SVG much of a workout, and its clock design had nothing new to say about time. In contrast, here's a new clock that exercises more of SVG's functionality and that says a lot more about time and our passage through it by displaying our position in the year, the month, the week, and the full day.
Potentially subtle points: The dark tick marks in the year ring denote the first day of each of month, while the normal tick marks indicate all of the other days. (Since 2008 is a leap year, there are currently 366 total tick marks in the year ring.) With the exception of the first one, the dark ticks in the month ring denote the start of weeks. (Note that, contrary to popular opinion, the week begins on Sunday in the Gregorian calendar, not on Monday.) Also, the text in this clock wants to be drawn using the Copperplate font, so if the text looks bad, it may be because your system lacks that font. (Of course, it could also be because you detest my choice of typeface.) Finally, it almost goes without saying that this clock contains detail that is barely visible when seen at the size show below. To get the full effect, open it in a new window, and make that window nice and big. Because it's SVG, it'll scale to any size.
Browser-specific oddities (for Safari 3.1.1 and Firefox 2.0.0.14) and implementation notes:
The SVG implementation in Safari is much faster than the one in Firefox.
The SVG implementation in Safari includes a bug that can prevent a portion of the area of the image affected by a change from being redrawn. In this clock, the second hand leaves behind artifacts as it approaches the fifteen second-markers.
Firefox treats font names as case-sensitive, but Safari does not.
When defining paths on which text will be drawn, Firefox insists that those path elements be children of a def element (or perhaps it's happy as long as something prevents the paths from being rendered). Safari doesn't care.
Firefox's SVG parser doesn't care if some attribute values violate their syntax. For example, transform='rotate(60 400 400' is perfectly acceptable to Firefox, even though the closing parenthesis is missing from the end of that rotate command. Safari won't tolerate that mistake.
Firefox will expend considerable resources redrawing elements that have moved so slightly that no change of any kind is visible at the rendered resolution. (Either Safari is smarter than that, or its faster SVG renderer hides the issue.) Firefox's SVG renderer can be placated to some extent if your code limits the precision of the positions, rotations, etc. that it calculates (limited, for example, to two decimal places), and only tells the SVG elements to change their position when their new positions differs from the previous positions.
Safari's SVG rendering fails abysmally if you change the size of the text on this page.
Firefox 3.0b5 can handle this clock when it is read from a file, but not as it exists, embedded in this page.
Javascript bas no built-in means of providing some basic date information like the internationalized name of each day of the week (even though it appears to know them), so the English names are hard-coded into this clock. The more I work with Javascript, the more I like Java.