Chronos is one of the many Smalltalk-related blogs syndicated on Planet Smalltalk

Discussion of the Essence# programming language, and related issues and technologies.

Blog Timezone: America/Los_Angeles [Winter: -0800 hhmm | Summer: -0700 hhmm] 
Your local time:  


Squeak Version of Chronos Published

[Note: Due to problems encountered when installing this version of Chronos into versions of Squeak prior to 3.8, the installation instructions have changed]

Thanks to Avi Bryant, who published a preliminay port of Chronos to Squeak which I have used as the basis for further refinement, there is now a highly functional version of Chronos for Squeak.

I am very appreciative of the contribution that Avi has made towards porting Chronos to Squeak (which includes, in addition to actual code, advice and problem reports.) I believe he intends to continue to contribute improvements. We would both welcome contributions from others.

The new version, unlike the version initially published, can read reference data from the file system--especially including time zone rulesets. It can also persist reference data in the local file system. The Chronos Time Zone Compiler can be installed, and it can be used to compile Chronos time zone rule files from the Olson zoneinfo source files.

However, the current Squeak version still does not have all the functionality of the VisualWorks version--although what's there and working provides a level of functionality that substantially exceeds that provided by the native (as packaged by the vendor/distributor) date/time libraries of either VisualWorks or Squeak (or the "out of the box" date/time libraries of any other programming language, for that matter.)

Here's what's currently not working/implemented in the Squeak version of Chronos:

  • Determination of the host system time zone (this would require new primitives or FFI function libraries--and is something that is not at all on my to-do list)

  • Support for any Locale other than #en_US--I may (or may not) decide to use the data published by the Common Locale Data Repository (CLDR) Project to provide such functionality for Squeak (and for other Smalltalk implementations as well,) but that won't happen for many months yet, if it happens at all

  • Convenience methods implemented in Squeak classes that leverage Chronos (e.g., String>>asTimezone, Number>>hours, etc.)--the issue here, of course, is interference with the native Chronology library's own such convenience methods (Note: Implementing such convenience methods for Chronos is the sole responsibility of the Squeak community)

  • Type-compatibility of Chronos classes with the analogous Chronology classes (Note: Implementing such type-compatibility methods for Chronos (or Chronos-compatibility for Chronology, for that matter) is the sole responsibility of the Squeak community)

If you browse the Chronos code, you will come accross example methods, and/or comments with executable example code, that depend upon Chronos functionality that is not currently implemented for the Squeak version (as specified above.) But the only missing functionality that is at all likely to impact most users (who stick with Chronos' default Locale and native API, don't expect there to be "convenience methods" that leverage Chronos in non-Chronos classes, and don't try to use Chronos and Chronology objects interchangeably) is the fact that the current version does not (and in fact, cannot, because Squeak cannot) determine the local time zone from the host operating system.

Of course, Squeak's native Chronology library also lacks such functionality--so Squeakers should be used to not having Squeak automatically determine their local time zone (by the way, that's a hard problem--although having Chronos installed makes it a much easier problem than it would be otherwise--as the VW version of Chronos demonstrates.)

Further mitigating the inability to discover the host system's local time zone is the fact that Squeak's system clock runs in local time, and not in Universal Time--which means that Squeak correctly reports the current date and time without needing to know what time zone it's in. Nevertheless, not knowing the local time zone can be a problem in some situations--especially when there are multiple users and/or machines in multiple time zones all trying to collaborate with each other. But that never happens, right? </sarcasm>

The new version of Chronos for Squeak can be obtained from the Chronos web site. Or you can use the following direct link to download the Chronos Date/Time Library for Squeak (based on Chronos version B1.150 for VisualWorks.)

Installation Instructions

  1. Extract all files from the downloaded archive file ( All the files start with the path-prefix "Chronos-B1.150/".

  2. Set up a folder with the image into which you will be installing Chronos.

  3. Move or copy the "Chronos-B1.150/time-zones" folder to the directory containing the image into which you will be installing Chronos, so that the "time-zones" folder is an immediate subdirectory of the directory containing your image (alternatively, move/copy your image into <wherever-you-extracted-the-files>/Chronos-B1.150/).

  4. Remove any previously-installed version of Chronos from your image (or use a "virgin" image.)

  5. File in Chronos-B1.150/ Answer "yes" both times the pop-up menu asks whether to auto-declare a shared-pool Dictionary. If you get the complaint that "English" is already defined, just "proceed." Save your image.

  6. File in either Chronos-B1.150/ or Chronos-B1.150/ (but not both!) is for Squeak 3.7 and later. is for versions of Squeak prior to 3.7. A Transcript window should open, and successful installation should then be reported to the Transcript window--along with other information, such as the pathnames to various sub-folders in the "time-zones" folder, and the selected language and country codes (which for Squeak, will always be English (#en) and United States (#US.)) Two warning messages may also be displayed about the inability to define the globals DateAndTime and Duration--that's not a problem, as long as the programmer understands that he must use the globals ScientificDuration and Timepoint instead of the ANSI-specified names (both of which are already taken by Chronology classes with the names at issue.)

  7. Older versions of Squeak may lack some of the VW-compatibility methods on which Chronos depends. One likely symptom of this problem would the error "Message not understood: #writeStream." One solution would be to backport the VW-compatibility methods from a later version of Squeak. Another solution would be to use a later version of Squeak.

  8. Save your image. Note that, although the reported date/time of installation will be the same as that reported by your operating system as local time, the offset and zone identification will probably not be correct for your location. That's what happens when a) the system clock reports local time, and b) there's no way to determine the local time zone from the host operating system. If the class "TimeZone" is resident in the image (a class belonging to Squeak's native Chronology date/time library,) Chronos uses the abbreviation and/or offset of the "DateAndTime localTimeZone" to do the best it can at setting the Chronos system time zone. Of course, if the Chronology time zone hasn't been set, that won't help you much.

  9. Set your local time zone, if the one chosen by Chronos is not correct. Here are some example expressions that can be evaluated as "do its" to set Chronos' system time zone (setting the Chronos system time zone will also set the Chronology local time zone to have the same offset, name and abbreviation as are currently in effect for the selected time zone):

    (Timezone at: #'Australia/Sydney') beSystem
    (Timezone at: #'Asia/Tokyo') beSystem
    (Timezone at: #'Asia/Calcutta') beSystem
    (Timezone at: #'Europe/Moscow') beSystem
    (Timezone at: #'Europe/Athens') beSystem
    (Timezone at: #'Europe/Berlin') beSystem
    (Timezone at: #'Europe/London') beSystem
    (Timezone at: #'America/New_York') beSystem
    (Timezone at: #'America/Chicago') beSystem
    (Timezone at: #'America/Denver') beSystem
    (Timezone at: #'America/Phoenix') beSystem
    (Timezone at: #'America/Los_Angeles') beSystem

To see the full list of time zone keys, open an inspector on the result of evaluating 'Timezone allCanonicalKeys'.

Helpful Hints

Instances of Chronos' Timepoint, YearMonthDay, TimeOfDay, ScientificDuration and ChronosTimezone classes can all be converted into their native Squeak equivalents by sending the message #asNative to the instance. Instances of Squeak's DateAndTime, Date, Time, Duration and TimeZone classes can be converted into their Chronos equivalents by sending the message #asChronosValue to the instance.

Because Chronos has both ScientificDurations (purely a number of fractional seconds, just like a Squeak Duration) and CivilDurations (which independently specify the number years, months, days, hours, minutes, seconds and fractions of a second represented by a temporal extent,) Chronos does not need any classes that are analogous to Squeak's Year, Month or Week classes. Instead, Chronos just uses the single class Timeperiod, with an appropriate CivilDuration, to provide the same functionality.

A Chronos YearMonthDay is more or less equivalent to a Squeak Date, except that a YearMonthDay is a point-in-time value whose resolution is one calendar day (civil time,) whereas a Squeak Date is implemented as an interval whose duration is one day (of exactly 86400 seconds, even when there are more or less than that many seconds in the day due to DST transitions and/or leap seconds.)

A Chronos Timepoint may be either invariant to Universal Time (same semantics as a java.util.Date--as required by the ANSI Smalltalk Standard) or invariant to nominal time (same semantics as a VisualWorks Timestamp.) A Timepoint that is invariant to Universal Time uses its value in Universal Time as its invariant, and compares as equal to all others whose value in Universal Time is the same. A Timepoint that is invariant to nominal time uses its nominal ("local") time as its invariant, and compares as equal to all others having the same nominal ("local") time. When the two types of time-invariance are mixed in the same expression, nominal-time-invariant semantics takes precedence. Universal-Time invariance is the default.

No comments: