Discovering the Local Time Zone--Why It's a Hard Problem

David T. Lewis lewis at mail.msen.com
Sat Feb 4 02:37:00 UTC 2006


On Thu, Feb 02, 2006 at 11:10:21PM -0800, Alan Lovejoy wrote:
> I have posted an essay on the matter of discovering the host system's time
> zone, so that either the VisualWorks or Squeak VM and/or image might be able
> synchronize with it. The essay is entitled "Discovering the Local Time
> Zone--Why It's a Hard Problem." 
>  
> The essay can be viewed at the following link:
> <http://www.chronos-st.org/Discovering%20the%20Local%20Time%20Zone--Why%20It
> 's%20a%20Hard%20Problem.html>
> http://www.chronos-st.org/Discovering%20the%20Local%20Time%20Zone--Why%20It'
> s%20a%20Hard%20Problem.html.
>  
> I thought this subject might be of some interest to the Squeak community.
>  
> --Alan

Thanks Alan, very nice writeup.

Here is some additional Squeak-specific info:

If you load TimeZoneDatabase from SqueakMap, there is documentation
of the oddities of time zones, daylight savings time, and leap seconds
as they pertain to Squeak. These are found in class TimeTransformTest,
method category "documentation":


Squeak Seconds Clock
-------------------------
The Squeak seconds clock represents the number of seconds since
the Smalltalk epoch. The Smalltalk epoch is defined as 1 January
1901.  The current value of this clock is available by evaluating
Time class>>totalSeconds, which calls the ioSeconds() function in
the Squeak virtual machine to obtain the current local time from
the underlying operating system.

This is a wall-clock time, in the sense that the Squeak seconds
clock corresponds to the setting of a clock on the wall located
(geographically) in the current time zone. When a daylight savings
time (DST) transition occurs, the hands on the wall clock are moved
either forward or backward. Similarly, the Squeak seconds clock
will jump forward or backward whenever a DST transition occurs.
The current Time in Squeak will also jump forward and backward
when DST transitions occur. Of course actual time proceeds forward
relentlessly, but the display of time on the wall clock will have
changed in order to make timekeeping more meaningful in the local
time zone. Likewise, the displayed value of DateAndTime in Squeak
will have suddenly adjusted itself to match the wall clock display.

In addition to DST transitions, leap seconds are occasionally added
to or removed from the world calendar. In principle, the seconds hand
on the wall clock is moved forward or back by one second whenever a
leap second is defined. Likewise, the Squeak seconds clock is (or
should be) adjusted forward or back when leap seconds occur.

It is also possible to define a notion of time as a magnitude,
independent of all of the adjustments that are made to wall clocks
in various locations around the world. Class PointInTime represents
this universal clock, and uses the convention of describing a point
in time as the total elapsed seconds since 1 January 1, 1970 in the
UTC time zone. These are seconds as would be reported by a very
accurate Caesium clock located in Greenwich, England. These seconds
increase continuously without regard for geographic time zones,
daylight savings time changes, or leap second adjustments used for
local displays of time on wall clocks.

It is always possible to derive the value of the Squeak seconds clock
from a PointInTime, given information about the local time zone offset
and leap seconds that are in effect as of that PointIntTime. The
TimeZoneDatabase provides this information. For any PointInTime and
LocalTimeTransform (time zone), the local time zone offset and leap
second count are known, and the Squeak seconds clock can be calculated.

However, the reverse transformation (Squeak seconds clock to PointInTime)
is not possible in the general case. To understand why, consider the
case of a Squeak system at 150 minutes (2 1/2 hours) after midnight on
Sunday, 31 October, 2004 in an Eastern Standard Time time zone. This is
a half hour after the "fall back" time zone change at the end of summer.
Assuming that we have kept track of our local time zone and leap seconds,
this occurs at the PointInTime 1099204222 seconds after 1 January, 1970.
If we check the Squeak seconds clock at this point in time, it reports
3276639000 seconds.

This is all well and good, but exactly one hour earlier the DST transition
had not yet happened. The PointInTime was 1099200622 seconds, and the
Squeak seconds clock was 3276639000, exactly the same value as the Squeak
seconds one hour later. Thus the Squeak seconds clock had the same value
at two completely different points in time. Therefore there are periods
of time during which it is not possible to determine which of two points
in time is the correct PointInTime for the Squeak seconds clock.

It is of course possible to add a primitive to Squeak that makes the
current PointInTime available directly. This, in conjunction with the
information in the TimeZoneDatabase, provides enough information to do
transformations from PointInTime to Squeak seconds and back without
ambiguity. Alternatively, a primitive that reports current time (either
UTC or local) along with current time zone offset provides the required
information.

As a related note, operating systems may not report time zone offset
correctly for points in time that occur outside of the current DST
setting. But if TimeZoneDatabase is available in the Squeak image and
a UTC seconds primitive is added, then Date and Time transformations
can be reliably calculated for any PointInTime within the domain of
the TimeZoneDatabase transforms.


UTC seconds clock
--------------------

UTC is a measure of time corresponding to the angular rotation of
the earth. As such, it is not a measure of time as measured by an
atomic clock. UTC time is kept in synchronization with atomic time
by the occasional insertion (or removal) of leap seconds in the UTC
clock, although historically other methods of adjusting the clock (e.g.
"elastic seconds") have been used, and the term "UTC" has had various
definitions over the years. The distinction between rotational time
(UTC) and atomic time can often be ignored. However, for purposes
of physics and astronomy, they are different concepts and the small
numerical differences between the two are significant.

Posix seconds are similar to UTC seconds, but are defined in such a
way that leap seconds are ignored. The Posix seconds clock is thus
effectively a "wall clock" representation of seconds, for which the
Posix clock is adjusted forward or back when a leap second occurs.
This is similar to the seconds clock in early Unix systems, which
were designed prior to the invention of leap seconds.

Class PointInTime is intended to represent atomic time, such that
time can be treated as a magnitude. Posix time varies from an atomic
seconds clock as leap seconds are applied. For this reason, the
conversion from PointInTime to and from Posix seconds should show
a difference corresponding to the number of leap seconds that have
been applied since 1 January, 1970.

If leap seconds are ignored, then Posix time and PointInTime seconds
produce the same count of seconds. Many time zone tables ignore leap
seconds, and many computer operating systems likewise ignore the
issue. For example, the LocalTimeTransform for "right/America/Detroit"
in a TimeZoneDatabase contains leap second rules, while the
"posix/America/Detroit" transform always answers zero leap seconds.
Both refer to the same geographical time zone, and for practical
purposes the "posix/America/Detroit" transform is an appropriate
choice to describe the time zone rules for Detroit, Michigan.

The LocalTimeTransforms in the TimeZoneDatabase contain transforms
with or without leap second tables. The "posix/America/Detroit"
transform ignores leap seconds, and is appropriate for a platform
that is configured according to Posix specifications, while the
"right/America/Detroit" transform accounts for leap seconds and
provided a more realistic count of actual elapsed seconds since
the Posix epoch.

It should not be assumed that the operatings system on which Squeak
is hosted will handle leap seconds consistently. BSD Unix systems
(including FreeBSD and Mac OSX) define the time_t system clock to
represent atomic clock seconds and providing time2posix() and
posix2time() functions for converting to and from Posix seconds.
This allows correct counting of actual seconds since the Posix epoch.
Other Unix and Linux systems may ignore leap seconds, and other
operating systems may also handle leap seconds differently.

For purposes of converting Time and Date in Squeak to and from
PointInTime seconds, we assume that Squeak will report its second
clock as Posix seconds offset by the current time zone offset,
regardless of the operating system and virtual machine on which
it is running.





More information about the Squeak-dev mailing list