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:  


A hidden twist in the black hole information paradox

A hidden twist in the black hole information paradox from

Professor Sam Braunstein, of the University of York's Department of Computer Science, and Dr Arun Pati, of the Institute of Physics, Sainik School, Bhubaneswar, India, have established that quantum information cannot be 'hidden' in conventional ways, or in Braunstein's words, "quantum information can run but it can't hide."



Smalltalk Considered Fun

Jeffrey Massung, in his blog post Smalltalk: An Application Language, states that programming in Smalltalk is fun. Jeffrey has formed that opinion over the past few months: He started using Smalltalk for the first time in late August 2006, developing a 2D game engine in Smalltalk.

I've had the same opinion since November, 1985--partly for the same reasons that Jeffrey mentions:

This is what Smalltalk does for me. I only write the code that matters. If I need to rename a class, all references everywhere else in my sources are automatically updated for me. If I change a method name, a browser window opens allowing me to see every caller so that I promptly fix them. These are just two of many, many, many features, all possible thanks to the reflective nature of Smalltalk, due in no small part, to it's object-oriented approach to problem solving.
When it is implemented well (dare I say "properly?"), this paradigm doesn't just constitute another tool in the toolbox; it is the toolbox, from which everything else stems.

Since I started this endeavor to create a 2D game engine in Smalltalk, I've not once - wait, let me reiterate this - not once have I stopped, and started over again. I'm still working in the same image I started with in late August, 2006. All my designs began with prototypes (*cough* hacks *cough*) inside the main code base, and yet the code is clean. When they worked, it took minutes to reorganize and re-factor the code properly. And when they didn't, it took minutes to strip out bad code, and restore the old.

I've honestly never had more fun programming! Smalltalk has actually made programming more fun than it already was. It allows me to iterate the code so fast! The speed at which I can try an idea, see what's wrong, switch gears, or continue molding until it's right is so ridiculously fast, that it's fun. It's been stated that programming isn't fun. Problem solving and code design are fun. Programming in Smalltalk is just that - all the time. It's fun.

This is why it's common practice to warn those who are about to learn Smalltalk that they may no longer have much desire to ever use anything else.

Jeffrey notes that the reasons that Smalltalk is such fun, and that the programmer's tools are so powerful and enabling, is because Smalltalk is so pervasively dynamic, so pervasively reflexive, and so pervasively open. And that's all quite true. But there's yet other reasons why Smalltalk is so much fun, and why it's so powerful: Smalltalk is pervasively simple, pervasively uniform and consistent, and it's metalevel is completely symmetric with its base level.

Smalltalk has a very high degree of symmetry, compared to any "Algol-like" language with which most programmers would be familiar. LISP exhibits the same high degree of symmetry. Broken symmetries are what make other languages not so fun.

Here's the symmetry, the uniformity, the consistency and the simplicity, stated concisely: All values are objects, all behavior is mediated by sending messages, and nothing is done by syntax when it can instead be done by sending messages to objects.

Smalltalk's high degree of symmetry has proven to be far more important than any theoretical benefits that might be garnered by the use of static type checking, primitive data types, syntactic sugar, or any of the other autocratic, control-freak gegaws that commonly decorate the mainstream languages.

Programmers of the world, throw off your chains. Your favorite programming languages are too complex, and have too little symmetry. It's time for a "Copernican Revolution," where programmers recognize that the curly-braced languages are based on overly-complex "epicycles," and that there's a much simpler approach.

Static/late binding is not the center of the universe, and attempting to make it so is robbing you of the fun you could be having.


Smalltalk Considered Unfriendly

Eric Dobbs' blog post (Playing Nice - what Perl's got that LISP and Smalltalk lack) hits the nail on the head: Smalltalk and LISP have not been as successful as Perl because LISP and Smalltalk want to be independent universes, hermetically sealed off from the rest of the world:

There's always been only one Perl; differing versions, sure, but you have never had to spend any time choosing whose Perl interpreter to use. More importantly, Perl began with the assumption that it would not be the only tool in your toolbox: it set out from the beginning to play well with others. By contrast, there have always been many flavors of LISP and Smalltalk any of which have tried to be pretty much everything you ever need.

Painting in broad strokes, David says Smalltalk's weakness is "at the boundaries:" when you want to try to do some typical unix system maintenance, or interfacing with underlying C libraries, or something similar. As long as you're staying within the Smalltalk environment, it completely rocks. But it's definitely painful if you try to reach outside. And it's especially painful if you want your code to work with different Smalltalks. What Perl got right was making it completely painless to integrate with its environment.

In some sense LISP wants to be on a LISP Machine and Smalltalk wants to be in its virtual machine, whereas Perl wants to go out and play with the other kids. The former languages are introverted and Perl is extroverted.

But, as Eric points out, that raises the question: "Why is Java more successful than LISP and Smalltalk?" After all, Java also wants to do everything itself, in its own idiosyncratic way, instead of relying on the host platform.

My answer: Java has not been as successful as it could have been, had it not been so fixated on always defining its own, separate culture (e.g, libraries, protocols, architectures, standards, etc.) And Java has peaked. It is losing ground against its competition, not continuing to advance. It owes its initial success to several unique factors, none of which are anywhere near as important as they were ten years ago: a) C++, b) the internet revolution, and c) the backing of Sun Microsystems, Inc. Java is now a legacy programming language, and its future will unfold in accord with that status.

Note that the languages that are beginning to overtake Java don't suffer from Java's antisocial attitude: Perl, Ruby, Python and C#. Yes, C#. Sun's strategy with Java was "same language, same architecture, same libraries--on all platforms." Microsoft's strategy with C# (and the CLR) is "any language, same architecture, same libraries, at least on Windows, and we're OK with others duplicating the CLR (and .Net) on other operating systems."

But I would also note that the the CLR, although it is better than the JVM at support for multiple langauges, is nevertheless not as friendly as it should be to deeply dynamic programming languages. That's one reason that the CLR-based languages aren't quite as "hot" as Ruby, Perl and Python.

Society is based on the theory that cooperation and collaboration are superior to conflict and confrontation. Peace is better than war. Friends are better than enemies. But Smalltalk and LISP have been trying to succeed as anti-social hermits, alone on their respective mountaintops (or up and away in their lonely balloons.) In the long term, I don't think that approach is likely to succeed. Smalltalk and LISP need to learn how to "play nice."

And there are two sides to "playing nice":
  1. Being willing and able to request services from your neighbors
  2. Being willing and able to answer requests for services from your neighbors

In other words, interoperability is reciprocal. You have to be able to play the role of a "broker," someone who "makes a market" in some set of services or commodities. That means you have to be equally willing to buy (make requests) or sell (respond to requests.)

From the point of view of the outside world, to the extent that Smalltalk and LISP provide any interoperability at all, it's almost all one sided: Smalltalk and LISP may deign to request something, but they don't offer any services in return. Unless and until that changes, I don't foresee either Smalltalk or LISP making much forward progress in the marketplace.

Of course, it's not that simple. There are really strong and compelling technical reasons why Smalltalk and LISP don't offer services that are easily consumable by foreigners. And there are also strong and compelling cultural reasons why Smalltalk and LISP prefer to build their own services and tools, instead of using the "community standard" services. The future of the two languages will depend on whether Smalltalkers and LISPers see these facts as reasons to do nothing, or as challenges to be overcome.

[Post Script:

I don't whether this is a direct response to my post, but Cincom (the folks behind VisualWorks) are making significant improvements to the ability of VisualWorks Smalltalk to "play nice" with other languages—as described in a blog post by James Robertson, the VisualWorks product manager: Better FFI all the way around]


Swarmbots: Robot builds itself for special tasks

Robot builds itself for special tasks from

In one of the latest studies on autonomous robots, scientists sat back and watched as their robot created itself out of smaller robotic modules. The result, called “swarm-bot,” comes in many varieties, depending on the assigned task and available components. As the current state of the art in autonomous self-assembly, swarm-bots offer insight into the potential versatility and robustness that robots may possess to perform missions beyond human abilities.



Handling various text file line-end conventions in VW

Martin Kobetic has posted an excellent tutorial on handling different text file line-end conventions in VisualWorks.

The Passport inter-Smalltalk portability library (on which the Chronos Date/Time Library depends) also provides a solution to the same problem:

  • UtilityFunction nextLineFrom: aStream

  • UtilityFunction skipToNextLineOf: aStream

Both of the above functions will work with any of the three text file line-end conventions currently encountered in the wild: CRLF (Windows,) LF (Unix/Linix/MacOS X) and CR (classic MacOS.)

Passport does not provide any support for writing text files using different line-end conventions, for two reasons:

  1. The external WriteStreams provided by most Smalltalk implementations will already convert CR to the host platform's line-end convention.

  2. Given the ability to read text files correctly, regardless of line-end convetion, there is not as much need to be able to write files with any particular line-end convention.

Chronos uses both of the above Passport functions in order to read time zone and other information from text files stored in the Chronos Time Zone Repository. Using those two Passport functions not only provides Chronos with inter-Smalltalk portability, it also means that a single version of the Chronos Time Zone Repository can be used on all host platforms, even when the text files were generated on a different operating system.

Macro, not micro: modified theories of gravity

Macro, not micro: modified theories of gravity from

When it comes to cosmology, the macro scale is important. As scientists search for the reasons behind the increasing rate at which the universe is expanding, they modify Einstein’s theory of gravity and delve into dark energy theories to explain this counter-intuitive phenomenon.


New energy source? Scientists convert heat to power using organic molecules

New energy source? Scientists convert heat to power using organic molecules from

Researchers at the University of California, Berkeley, have successfully generated electricity from heat by trapping organic molecules between metal nanoparticles, an achievement that could pave the way toward the development of a new source for energy.



Chronos Time Zone Repository Version 2007b Published

Version 2007b of the Chronos Time Zone Repository has been published. It is based on version 2007b of the Olson Time Zone Database.


Chronos Roadmap

Current Task: Implement iCal Recurrence Rules

Planned Tasks/Enhancements/Features:

  • Implement full support for "Business Day Conventions," including addition/subtraction of business days (supplementing the already-supported "business days between dates" functionality.) Business date conventions specify the business rule for adjusting dates so that they don't fall on holidays, such as "next business day," "preceding business day," "nearest business day, "next business day in same month--adjusting to previous business day if necessary," "previous business day in same month--adjusting to next business day if necessary"

  • Implement multiple timescales (e.g., UT0, UT1, UTC, TAI, apparent
    solar...) Will at least implement UT1 and UTC--but the architecture will be extensible.

  • Complete all documentation.

  • Implement the Chinese Calendar.

  • Implement the Astronomical Hijri (Islamic) Calendar.

  • Implement conformance to the IANA Time Zone Registry Specification


Researchers Create Tiny, Self-Propelled Devices

Researchers Create Tiny, Self-Propelled Devices from

North Carolina State University scientists have figured out a method to supply microscopic devices with enough energy to not only allow them to propel themselves through liquid – a difficult function in its own right – but also to perform some other functions, like emitting light.



In the beginning was the bit

From New Scientist, In the beginning was the bit:

"NOBODY understands quantum mechanics," lamented Richard Feynman. But Anton Zeilinger at the University of Vienna aims to prove him wrong. His research group has demonstrated the futuristic phenomena of quantum teleportation and quantum encryption, and these successes have encouraged Zeilinger to search for the essence of quantum mechanics--the irreducible kernel from which everything else flows. He believes that he has found it. If he is right, all the mysteries of the quantum world will turn out to be inescapable consequences of a single, simple idea.
Zeilinger and Brukner...introduce a three-dimensional space they call information space. The relationship between 2D Hilbert space and 3D information space is a bit like the relationship between an accurate perspective drawing and a real, three-dimensional object. This new space is much closer to our reality, as its axes correspond to the answers of yes or no questions about an elementary system. An electron's spin can be measured, or quantised, along the x, y, or z axes of real space, which gives the three dimensions of information space a clear correspondence with reality. In other two-state systems the connections are not so obvious, but three independent propositions will always exhaust the possibilities.

Any quantum system has to describe how states change over time, so the point in information space has to move. It seemed natural to Zeilinger and Brukner to have the point move as if it were a real, classical object. So they used the mechanical equation that governs the motion of bullets and billiard balls. When translated back into its equivalent form in Hilbert space, it turns out to be none other than Schrödinger's equation.

[Read more]


Quantum Quirk: Stopped Laser Pulse Reappears a Short Distance Away

From Scientific American:

Harvard University researchers have halted a pulse of laser light in its tracks and revived it a fraction of a millimeter away. Here's the twist: they stopped it in a cloud of supercold sodium atoms, known as a Bose-Einstein condensate (BEC), and then restarted it in a second, distinct BEC as though the pulse had spookily jumped between the two locations.



The times they are a-changing...

The last time the rules for entering and leaving Daylight Saving Time changed in North America was 1987. That was a very different world than we have today. It was significantly less automated, significantly less computerized and significantly less dependent on computers and software for accomplishing mission critical tasks.

So, on an upcoming fateful day in March 2007, when legal, civil time in North America's "Eastern Time Zone" jumps in an instant from 2007-03-11T01:59:59.99999999...-05:00 to 2007-03-11T03:00:00-04:00, what will happen? How many computer systems, and devices using embedded computer systems, will fail to recognize that civil time is suddenly an hour later than it had been? And what consequences are likely to ensue?

I strongly suspect (to put it mildly) that the number of systems that won't have the correct civil time will be decidedly non-trivial. But the likely consequences of that timekeeping failure are much harder to guess. One likely result will be users complaining about 1-hour time-of-day discrepancies. The most likely cause of serious malfunctions will be situations where two or more computer systems colloborate together in such a way that clock synchronization matters, with some (but not all) of them still using the old time zone rules for North America.

The best way to handle the problems that might arise due to your computers using the wrong time zone rules is to make sure all your computers know the new rules. If you do nothing, it's highly likely that your computers won't know anything about it (and that's true from Mainframes to PDAs, especially including computers that use Unix or Windows.)

Here are some resources with helpful information about updating the time zone rules for computers of various types:

But updating the operating system may not be sufficient. For reasons I won't go into here, there are many applications that don't rely on the OS to tell them what the time zone rules happen to be. One prominent example is Java. Another that may be of some interest to my intended audience on this blog (the community of Smalltalk programmers,) would be one of the most widely used Smalltalk variants: VisualWorks.

For information about updating Java applications with the new time zone rules, refer to the following:
Smalltalkers who use the Chronos Date/Time Library in their Smalltalk applications, and who obtained any version of the Chronos Time Zone Repository after late-August 2005 (a year and half ago!) already have the new time zone rules for North America. This is because the new rules were known as soon as Congress passed the Energy Policy Act of 2005 (in the Summer of 2005,) and also because the Chronos time zone rule sets are able to represent not only the rules for the current year, but also rules for other either past or future years that differ from those currently in effect.

As for those Smalltalkers who don't use Chronos in their applications, the situation is as follows:

VisualWorks: The time zone rules must be updated. My earlier blog post, VW: 2007 TimeZone settings for North America, explains how to do so.

Squeak: Those using the "out-of-the-box" Chronology classes don't need to do anything. But that's not because the Chronology classes know all about time zones, but rather because they don't. For many situations, there is no need for the Chronology classes to know anything about time zones. Squeak relies on the operating system to tell it what the local time currently is. That's a very simple approach...which stops working as soon as you need to do any of the following things:
  • Convert a date/time from some other time zone into your local time (because you don't know what your offset from Universal Time happens to be, and may also not know the offset of the other time zone.)
  • Convert a local date/time to some other time zone (for the same reasons as above.)
  • Correctly compute the amount of physical, elapsed time between two points in time (because you won't know whether the time zone offsets of the two points in time were the same, since there may have been one or more intervening DST transitions; or worse, the two points in time may not even have been intended to represent time in the same time zone.)
  • Correctly compute the point in time that results when adding a duration to a point in time (again, because you won't know whether the offset will be the same, since the offset may be different even a fraction of a second earlier or later.)

But those using Squeak have two other options. One is Chronos, which has already been discussed. The other is the David T. Lewis' TimeZoneDatabase (which functions in a way very similar to Chronos, at least as far as time zones are concerned.) Just like Chronos, the TimeZoneDatabase relies on an external repository of time zone rules--and both use the Olson Time Zone Database as the source of those rules. On Unix-based hosts, the TimeZoneDatabase can be configured to use the same binary "tzfiles" as Unix itself uses, at the same disk location--which means that updating the operating system's time zone rules also updates the TimeZoneDatabase. But on non-Unix based systems, the "tzfiles" must be updated separately.

Dolphin Smalltalk: Dolphin uses Windows system calls to get the current local time. Although Dolphin very helpfully provides the ability to get time zone information from the Windows Registry, its native TimeStamp class doesn't use that capability to provide time-zone-aware date/time behavior. Chronos is also available for Dolphin.

Most other Smalltalk systems are essentially similar to either Squeak or Dolphin, as far as time zone functionality is concerned.

But all this raises a very good question: Why are time zones such a hard problem?

Frequency Comb' Technique Reveals Colors And Intensity Of All Lightwaves Simultaneously

From Science Daily:

Physicists at the Commerce Department's National Institute of Standards and Technology (NIST) have taken the first ever two-dimensional pictures of a "frequency comb," providing extra information that enhances the comb's usefulness in optical atomic clocks, secure high-bandwidth communications, real-time chemical analysis, remote sensing, and the ultimate in precision control of atoms and molecules.
The new technique will enable scientists to measure and manipulate optical frequencies in a massively parallel manner, Diddams says. The frequency brush could enable more precise control of individual frequencies than is currently possible in high-bandwidth communications, making it possible to reliably pack more channels with greater security into the same spectrum. The technique also may be useful in optical signal processing--synthesis and control of light as easily as electronic signals are currently manipulated--that could boost the power of surveillance, remote sensing, trace gas detection and high-speed computing systems. And it could enable the "ultimate" in precision control of atoms and molecules, a valuable tool in many areas of science, Diddams says.

Flow of tiny bubbles mimics computer circuitry

Flow of tiny bubbles mimics computer circuitry from

In work that could dramatically boost the capabilities of "lab on a chip" devices, MIT researchers have created a way to use tiny bubbles to mimic the capabilities of a computer.



When's the next (or previous) DST offset transition?

How can you tell programmatically when the next (or previous) DST (daylight saving time) offset transition will occur (has occurred)--other than by using a brute-force approach where one checks the offset of successive points in time, each one second later than the previous one? Few date/time libraries provide any support for such functionality (and many don't even provide support for real-world time zones where offsets change during the year according to a set of rules.)

Although it's possible to use Chronos to discover all the moments when a time zone's offset, name or abbreviation changes (and not just by the brute-force method mentioned above,) the bad news is that for a developer who casually uses Chronos to figure out how to code that functionality would probably require not only a bit of research, but also the writing of some non-trivial amount of new code.

So, the next release of Chronos (which is not yet available) will provide a simple, easy-to-use API for enumerating through all the moments when a time zone's offset changes, so that developers who use Chronos won't have to do as much research, and won't have to write anywhere near as much new new code, in order to find the next (or previous) offset transition for a time zone. Using this new API, the following list of every offset transition in the America/Los_Angeles time zone, from the very first one in 1883 until the arbitrarily chosen end-year of 2050, can easily be generated:

1883-11-18T12:00:00-08:00  [1883-11-18T20:00:00Z] -07:52:58 -> -08:00  {-2717640000}
1918-03-31T03:00:00-07:00 [1918-03-31T10:00:00Z] -08:00 -> -07:00 {-1633269600}
1918-10-27T01:00:00-08:00 [1918-10-27T09:00:00Z] -07:00 -> -08:00 {-1615129200}
1919-03-30T03:00:00-07:00 [1919-03-30T10:00:00Z] -08:00 -> -07:00 {-1601820000}
1919-10-26T01:00:00-08:00 [1919-10-26T09:00:00Z] -07:00 -> -08:00 {-1583679600}
1942-02-09T03:00:00-07:00 [1942-02-09T10:00:00Z] -08:00 -> -07:00 {-880207200}
1945-08-14T16:00:00-07:00 [1945-08-14T23:00:00Z] -07:00 -> -07:00 {-769395600}
1945-09-30T01:00:00-08:00 [1945-09-30T09:00:00Z] -07:00 -> -08:00 {-765385200}
1948-03-14T03:00:00-07:00 [1948-03-14T10:00:00Z] -08:00 -> -07:00 {-687967200}
1949-01-01T01:00:00-08:00 [1949-01-01T09:00:00Z] -07:00 -> -08:00 {-662655600}
1950-04-30T03:00:00-07:00 [1950-04-30T10:00:00Z] -08:00 -> -07:00 {-620834400}
1950-09-24T01:00:00-08:00 [1950-09-24T09:00:00Z] -07:00 -> -08:00 {-608137200}
1951-04-29T03:00:00-07:00 [1951-04-29T10:00:00Z] -08:00 -> -07:00 {-589384800}
1951-09-30T01:00:00-08:00 [1951-09-30T09:00:00Z] -07:00 -> -08:00 {-576082800}
1952-04-27T03:00:00-07:00 [1952-04-27T10:00:00Z] -08:00 -> -07:00 {-557935200}
1952-09-28T01:00:00-08:00 [1952-09-28T09:00:00Z] -07:00 -> -08:00 {-544633200}
1953-04-26T03:00:00-07:00 [1953-04-26T10:00:00Z] -08:00 -> -07:00 {-526485600}
1953-09-27T01:00:00-08:00 [1953-09-27T09:00:00Z] -07:00 -> -08:00 {-513183600}
1954-04-25T03:00:00-07:00 [1954-04-25T10:00:00Z] -08:00 -> -07:00 {-495036000}
1954-09-26T01:00:00-08:00 [1954-09-26T09:00:00Z] -07:00 -> -08:00 {-481734000}
1955-04-24T03:00:00-07:00 [1955-04-24T10:00:00Z] -08:00 -> -07:00 {-463586400}
1955-09-25T01:00:00-08:00 [1955-09-25T09:00:00Z] -07:00 -> -08:00 {-450284400}
1956-04-29T03:00:00-07:00 [1956-04-29T10:00:00Z] -08:00 -> -07:00 {-431532000}
1956-09-30T01:00:00-08:00 [1956-09-30T09:00:00Z] -07:00 -> -08:00 {-418230000}
1957-04-28T03:00:00-07:00 [1957-04-28T10:00:00Z] -08:00 -> -07:00 {-400082400}
1957-09-29T01:00:00-08:00 [1957-09-29T09:00:00Z] -07:00 -> -08:00 {-386780400}
1958-04-27T03:00:00-07:00 [1958-04-27T10:00:00Z] -08:00 -> -07:00 {-368632800}
1958-09-28T01:00:00-08:00 [1958-09-28T09:00:00Z] -07:00 -> -08:00 {-355330800}
1959-04-26T03:00:00-07:00 [1959-04-26T10:00:00Z] -08:00 -> -07:00 {-337183200}
1959-09-27T01:00:00-08:00 [1959-09-27T09:00:00Z] -07:00 -> -08:00 {-323881200}
1960-04-24T03:00:00-07:00 [1960-04-24T10:00:00Z] -08:00 -> -07:00 {-305733600}
1960-09-25T01:00:00-08:00 [1960-09-25T09:00:00Z] -07:00 -> -08:00 {-292431600}
1961-04-30T03:00:00-07:00 [1961-04-30T10:00:00Z] -08:00 -> -07:00 {-273679200}
1961-09-24T01:00:00-08:00 [1961-09-24T09:00:00Z] -07:00 -> -08:00 {-260982000}
1962-04-29T03:00:00-07:00 [1962-04-29T10:00:00Z] -08:00 -> -07:00 {-242229600}
1962-10-28T01:00:00-08:00 [1962-10-28T09:00:00Z] -07:00 -> -08:00 {-226508400}
1963-04-28T03:00:00-07:00 [1963-04-28T10:00:00Z] -08:00 -> -07:00 {-210780000}
1963-10-27T01:00:00-08:00 [1963-10-27T09:00:00Z] -07:00 -> -08:00 {-195058800}
1964-04-26T03:00:00-07:00 [1964-04-26T10:00:00Z] -08:00 -> -07:00 {-179330400}
1964-10-25T01:00:00-08:00 [1964-10-25T09:00:00Z] -07:00 -> -08:00 {-163609200}
1965-04-25T03:00:00-07:00 [1965-04-25T10:00:00Z] -08:00 -> -07:00 {-147880800}
1965-10-31T01:00:00-08:00 [1965-10-31T09:00:00Z] -07:00 -> -08:00 {-131554800}
1966-04-24T03:00:00-07:00 [1966-04-24T10:00:00Z] -08:00 -> -07:00 {-116431200}
1966-10-30T01:00:00-08:00 [1966-10-30T09:00:00Z] -07:00 -> -08:00 {-100105200}
1967-04-30T03:00:00-07:00 [1967-04-30T10:00:00Z] -08:00 -> -07:00 {-84376800}
1967-10-29T01:00:00-08:00 [1967-10-29T09:00:00Z] -07:00 -> -08:00 {-68655600}
1968-04-28T03:00:00-07:00 [1968-04-28T10:00:00Z] -08:00 -> -07:00 {-52927200}
1968-10-27T01:00:00-08:00 [1968-10-27T09:00:00Z] -07:00 -> -08:00 {-37206000}
1969-04-27T03:00:00-07:00 [1969-04-27T10:00:00Z] -08:00 -> -07:00 {-21477600}
1969-10-26T01:00:00-08:00 [1969-10-26T09:00:00Z] -07:00 -> -08:00 {-5756400}
1970-04-26T03:00:00-07:00 [1970-04-26T10:00:00Z] -08:00 -> -07:00 {9972000}
1970-10-25T01:00:00-08:00 [1970-10-25T09:00:00Z] -07:00 -> -08:00 {25693200}
1971-04-25T03:00:00-07:00 [1971-04-25T10:00:00Z] -08:00 -> -07:00 {41421600}
1971-10-31T01:00:00-08:00 [1971-10-31T09:00:00Z] -07:00 -> -08:00 {57747600}
1972-04-30T03:00:00-07:00 [1972-04-30T10:00:00Z] -08:00 -> -07:00 {73476000}
1972-10-29T01:00:00-08:00 [1972-10-29T09:00:00Z] -07:00 -> -08:00 {89197200}
1973-04-29T03:00:00-07:00 [1973-04-29T10:00:00Z] -08:00 -> -07:00 {104925600}
1973-10-28T01:00:00-08:00 [1973-10-28T09:00:00Z] -07:00 -> -08:00 {120646800}
1974-01-06T03:00:00-07:00 [1974-01-06T10:00:00Z] -08:00 -> -07:00 {126698400}
1974-10-27T01:00:00-08:00 [1974-10-27T09:00:00Z] -07:00 -> -08:00 {152096400}
1975-02-23T03:00:00-07:00 [1975-02-23T10:00:00Z] -08:00 -> -07:00 {162381600}
1975-10-26T01:00:00-08:00 [1975-10-26T09:00:00Z] -07:00 -> -08:00 {183546000}
1976-04-25T03:00:00-07:00 [1976-04-25T10:00:00Z] -08:00 -> -07:00 {199274400}
1976-10-31T01:00:00-08:00 [1976-10-31T09:00:00Z] -07:00 -> -08:00 {215600400}
1977-04-24T03:00:00-07:00 [1977-04-24T10:00:00Z] -08:00 -> -07:00 {230724000}
1977-10-30T01:00:00-08:00 [1977-10-30T09:00:00Z] -07:00 -> -08:00 {247050000}
1978-04-30T03:00:00-07:00 [1978-04-30T10:00:00Z] -08:00 -> -07:00 {262778400}
1978-10-29T01:00:00-08:00 [1978-10-29T09:00:00Z] -07:00 -> -08:00 {278499600}
1979-04-29T03:00:00-07:00 [1979-04-29T10:00:00Z] -08:00 -> -07:00 {294228000}
1979-10-28T01:00:00-08:00 [1979-10-28T09:00:00Z] -07:00 -> -08:00 {309949200}
1980-04-27T03:00:00-07:00 [1980-04-27T10:00:00Z] -08:00 -> -07:00 {325677600}
1980-10-26T01:00:00-08:00 [1980-10-26T09:00:00Z] -07:00 -> -08:00 {341398800}
1981-04-26T03:00:00-07:00 [1981-04-26T10:00:00Z] -08:00 -> -07:00 {357127200}
1981-10-25T01:00:00-08:00 [1981-10-25T09:00:00Z] -07:00 -> -08:00 {372848400}
1982-04-25T03:00:00-07:00 [1982-04-25T10:00:00Z] -08:00 -> -07:00 {388576800}
1982-10-31T01:00:00-08:00 [1982-10-31T09:00:00Z] -07:00 -> -08:00 {404902800}
1983-04-24T03:00:00-07:00 [1983-04-24T10:00:00Z] -08:00 -> -07:00 {420026400}
1983-10-30T01:00:00-08:00 [1983-10-30T09:00:00Z] -07:00 -> -08:00 {436352400}
1984-04-29T03:00:00-07:00 [1984-04-29T10:00:00Z] -08:00 -> -07:00 {452080800}
1984-10-28T01:00:00-08:00 [1984-10-28T09:00:00Z] -07:00 -> -08:00 {467802000}
1985-04-28T03:00:00-07:00 [1985-04-28T10:00:00Z] -08:00 -> -07:00 {483530400}
1985-10-27T01:00:00-08:00 [1985-10-27T09:00:00Z] -07:00 -> -08:00 {499251600}
1986-04-27T03:00:00-07:00 [1986-04-27T10:00:00Z] -08:00 -> -07:00 {514980000}
1986-10-26T01:00:00-08:00 [1986-10-26T09:00:00Z] -07:00 -> -08:00 {530701200}
1987-04-05T03:00:00-07:00 [1987-04-05T10:00:00Z] -08:00 -> -07:00 {544615200}
1987-10-25T01:00:00-08:00 [1987-10-25T09:00:00Z] -07:00 -> -08:00 {562150800}
1988-04-03T03:00:00-07:00 [1988-04-03T10:00:00Z] -08:00 -> -07:00 {576064800}
1988-10-30T01:00:00-08:00 [1988-10-30T09:00:00Z] -07:00 -> -08:00 {594205200}
1989-04-02T03:00:00-07:00 [1989-04-02T10:00:00Z] -08:00 -> -07:00 {607514400}
1989-10-29T01:00:00-08:00 [1989-10-29T09:00:00Z] -07:00 -> -08:00 {625654800}
1990-04-01T03:00:00-07:00 [1990-04-01T10:00:00Z] -08:00 -> -07:00 {638964000}
1990-10-28T01:00:00-08:00 [1990-10-28T09:00:00Z] -07:00 -> -08:00 {657104400}
1991-04-07T03:00:00-07:00 [1991-04-07T10:00:00Z] -08:00 -> -07:00 {671018400}
1991-10-27T01:00:00-08:00 [1991-10-27T09:00:00Z] -07:00 -> -08:00 {688554000}
1992-04-05T03:00:00-07:00 [1992-04-05T10:00:00Z] -08:00 -> -07:00 {702468000}
1992-10-25T01:00:00-08:00 [1992-10-25T09:00:00Z] -07:00 -> -08:00 {720003600}
1993-04-04T03:00:00-07:00 [1993-04-04T10:00:00Z] -08:00 -> -07:00 {733917600}
1993-10-31T01:00:00-08:00 [1993-10-31T09:00:00Z] -07:00 -> -08:00 {752058000}
1994-04-03T03:00:00-07:00 [1994-04-03T10:00:00Z] -08:00 -> -07:00 {765367200}
1994-10-30T01:00:00-08:00 [1994-10-30T09:00:00Z] -07:00 -> -08:00 {783507600}
1995-04-02T03:00:00-07:00 [1995-04-02T10:00:00Z] -08:00 -> -07:00 {796816800}
1995-10-29T01:00:00-08:00 [1995-10-29T09:00:00Z] -07:00 -> -08:00 {814957200}
1996-04-07T03:00:00-07:00 [1996-04-07T10:00:00Z] -08:00 -> -07:00 {828871200}
1996-10-27T01:00:00-08:00 [1996-10-27T09:00:00Z] -07:00 -> -08:00 {846406800}
1997-04-06T03:00:00-07:00 [1997-04-06T10:00:00Z] -08:00 -> -07:00 {860320800}
1997-10-26T01:00:00-08:00 [1997-10-26T09:00:00Z] -07:00 -> -08:00 {877856400}
1998-04-05T03:00:00-07:00 [1998-04-05T10:00:00Z] -08:00 -> -07:00 {891770400}
1998-10-25T01:00:00-08:00 [1998-10-25T09:00:00Z] -07:00 -> -08:00 {909306000}
1999-04-04T03:00:00-07:00 [1999-04-04T10:00:00Z] -08:00 -> -07:00 {923220000}
1999-10-31T01:00:00-08:00 [1999-10-31T09:00:00Z] -07:00 -> -08:00 {941360400}
2000-04-02T03:00:00-07:00 [2000-04-02T10:00:00Z] -08:00 -> -07:00 {954669600}
2000-10-29T01:00:00-08:00 [2000-10-29T09:00:00Z] -07:00 -> -08:00 {972810000}
2001-04-01T03:00:00-07:00 [2001-04-01T10:00:00Z] -08:00 -> -07:00 {986119200}
2001-10-28T01:00:00-08:00 [2001-10-28T09:00:00Z] -07:00 -> -08:00 {1004259600}
2002-04-07T03:00:00-07:00 [2002-04-07T10:00:00Z] -08:00 -> -07:00 {1018173600}
2002-10-27T01:00:00-08:00 [2002-10-27T09:00:00Z] -07:00 -> -08:00 {1035709200}
2003-04-06T03:00:00-07:00 [2003-04-06T10:00:00Z] -08:00 -> -07:00 {1049623200}
2003-10-26T01:00:00-08:00 [2003-10-26T09:00:00Z] -07:00 -> -08:00 {1067158800}
2004-04-04T03:00:00-07:00 [2004-04-04T10:00:00Z] -08:00 -> -07:00 {1081072800}
2004-10-31T01:00:00-08:00 [2004-10-31T09:00:00Z] -07:00 -> -08:00 {1099213200}
2005-04-03T03:00:00-07:00 [2005-04-03T10:00:00Z] -08:00 -> -07:00 {1112522400}
2005-10-30T01:00:00-08:00 [2005-10-30T09:00:00Z] -07:00 -> -08:00 {1130662800}
2006-04-02T03:00:00-07:00 [2006-04-02T10:00:00Z] -08:00 -> -07:00 {1143972000}
2006-10-29T01:00:00-08:00 [2006-10-29T09:00:00Z] -07:00 -> -08:00 {1162112400}
2007-03-11T03:00:00-07:00 [2007-03-11T10:00:00Z] -08:00 -> -07:00 {1173607200}
2007-11-04T01:00:00-08:00 [2007-11-04T09:00:00Z] -07:00 -> -08:00 {1194166800}
2008-03-09T03:00:00-07:00 [2008-03-09T10:00:00Z] -08:00 -> -07:00 {1205056800}
2008-11-02T01:00:00-08:00 [2008-11-02T09:00:00Z] -07:00 -> -08:00 {1225616400}
2009-03-08T03:00:00-07:00 [2009-03-08T10:00:00Z] -08:00 -> -07:00 {1236506400}
2009-11-01T01:00:00-08:00 [2009-11-01T09:00:00Z] -07:00 -> -08:00 {1257066000}
2010-03-14T03:00:00-07:00 [2010-03-14T10:00:00Z] -08:00 -> -07:00 {1268560800}
2010-11-07T01:00:00-08:00 [2010-11-07T09:00:00Z] -07:00 -> -08:00 {1289120400}
2011-03-13T03:00:00-07:00 [2011-03-13T10:00:00Z] -08:00 -> -07:00 {1300010400}
2011-11-06T01:00:00-08:00 [2011-11-06T09:00:00Z] -07:00 -> -08:00 {1320570000}
2012-03-11T03:00:00-07:00 [2012-03-11T10:00:00Z] -08:00 -> -07:00 {1331460000}
2012-11-04T01:00:00-08:00 [2012-11-04T09:00:00Z] -07:00 -> -08:00 {1352019600}
2013-03-10T03:00:00-07:00 [2013-03-10T10:00:00Z] -08:00 -> -07:00 {1362909600}
2013-11-03T01:00:00-08:00 [2013-11-03T09:00:00Z] -07:00 -> -08:00 {1383469200}
2014-03-09T03:00:00-07:00 [2014-03-09T10:00:00Z] -08:00 -> -07:00 {1394359200}
2014-11-02T01:00:00-08:00 [2014-11-02T09:00:00Z] -07:00 -> -08:00 {1414918800}
2015-03-08T03:00:00-07:00 [2015-03-08T10:00:00Z] -08:00 -> -07:00 {1425808800}
2015-11-01T01:00:00-08:00 [2015-11-01T09:00:00Z] -07:00 -> -08:00 {1446368400}
2016-03-13T03:00:00-07:00 [2016-03-13T10:00:00Z] -08:00 -> -07:00 {1457863200}
2016-11-06T01:00:00-08:00 [2016-11-06T09:00:00Z] -07:00 -> -08:00 {1478422800}
2017-03-12T03:00:00-07:00 [2017-03-12T10:00:00Z] -08:00 -> -07:00 {1489312800}
2017-11-05T01:00:00-08:00 [2017-11-05T09:00:00Z] -07:00 -> -08:00 {1509872400}
2018-03-11T03:00:00-07:00 [2018-03-11T10:00:00Z] -08:00 -> -07:00 {1520762400}
2018-11-04T01:00:00-08:00 [2018-11-04T09:00:00Z] -07:00 -> -08:00 {1541322000}
2019-03-10T03:00:00-07:00 [2019-03-10T10:00:00Z] -08:00 -> -07:00 {1552212000}
2019-11-03T01:00:00-08:00 [2019-11-03T09:00:00Z] -07:00 -> -08:00 {1572771600}
2020-03-08T03:00:00-07:00 [2020-03-08T10:00:00Z] -08:00 -> -07:00 {1583661600}
2020-11-01T01:00:00-08:00 [2020-11-01T09:00:00Z] -07:00 -> -08:00 {1604221200}
2021-03-14T03:00:00-07:00 [2021-03-14T10:00:00Z] -08:00 -> -07:00 {1615716000}
2021-11-07T01:00:00-08:00 [2021-11-07T09:00:00Z] -07:00 -> -08:00 {1636275600}
2022-03-13T03:00:00-07:00 [2022-03-13T10:00:00Z] -08:00 -> -07:00 {1647165600}
2022-11-06T01:00:00-08:00 [2022-11-06T09:00:00Z] -07:00 -> -08:00 {1667725200}
2023-03-12T03:00:00-07:00 [2023-03-12T10:00:00Z] -08:00 -> -07:00 {1678615200}
2023-11-05T01:00:00-08:00 [2023-11-05T09:00:00Z] -07:00 -> -08:00 {1699174800}
2024-03-10T03:00:00-07:00 [2024-03-10T10:00:00Z] -08:00 -> -07:00 {1710064800}
2024-11-03T01:00:00-08:00 [2024-11-03T09:00:00Z] -07:00 -> -08:00 {1730624400}
2025-03-09T03:00:00-07:00 [2025-03-09T10:00:00Z] -08:00 -> -07:00 {1741514400}
2025-11-02T01:00:00-08:00 [2025-11-02T09:00:00Z] -07:00 -> -08:00 {1762074000}
2026-03-08T03:00:00-07:00 [2026-03-08T10:00:00Z] -08:00 -> -07:00 {1772964000}
2026-11-01T01:00:00-08:00 [2026-11-01T09:00:00Z] -07:00 -> -08:00 {1793523600}
2027-03-14T03:00:00-07:00 [2027-03-14T10:00:00Z] -08:00 -> -07:00 {1805018400}
2027-11-07T01:00:00-08:00 [2027-11-07T09:00:00Z] -07:00 -> -08:00 {1825578000}
2028-03-12T03:00:00-07:00 [2028-03-12T10:00:00Z] -08:00 -> -07:00 {1836468000}
2028-11-05T01:00:00-08:00 [2028-11-05T09:00:00Z] -07:00 -> -08:00 {1857027600}
2029-03-11T03:00:00-07:00 [2029-03-11T10:00:00Z] -08:00 -> -07:00 {1867917600}
2029-11-04T01:00:00-08:00 [2029-11-04T09:00:00Z] -07:00 -> -08:00 {1888477200}
2030-03-10T03:00:00-07:00 [2030-03-10T10:00:00Z] -08:00 -> -07:00 {1899367200}
2030-11-03T01:00:00-08:00 [2030-11-03T09:00:00Z] -07:00 -> -08:00 {1919926800}
2031-03-09T03:00:00-07:00 [2031-03-09T10:00:00Z] -08:00 -> -07:00 {1930816800}
2031-11-02T01:00:00-08:00 [2031-11-02T09:00:00Z] -07:00 -> -08:00 {1951376400}
2032-03-14T03:00:00-07:00 [2032-03-14T10:00:00Z] -08:00 -> -07:00 {1962871200}
2032-11-07T01:00:00-08:00 [2032-11-07T09:00:00Z] -07:00 -> -08:00 {1983430800}
2033-03-13T03:00:00-07:00 [2033-03-13T10:00:00Z] -08:00 -> -07:00 {1994320800}
2033-11-06T01:00:00-08:00 [2033-11-06T09:00:00Z] -07:00 -> -08:00 {2014880400}
2034-03-12T03:00:00-07:00 [2034-03-12T10:00:00Z] -08:00 -> -07:00 {2025770400}
2034-11-05T01:00:00-08:00 [2034-11-05T09:00:00Z] -07:00 -> -08:00 {2046330000}
2035-03-11T03:00:00-07:00 [2035-03-11T10:00:00Z] -08:00 -> -07:00 {2057220000}
2035-11-04T01:00:00-08:00 [2035-11-04T09:00:00Z] -07:00 -> -08:00 {2077779600}
2036-03-09T03:00:00-07:00 [2036-03-09T10:00:00Z] -08:00 -> -07:00 {2088669600}
2036-11-02T01:00:00-08:00 [2036-11-02T09:00:00Z] -07:00 -> -08:00 {2109229200}
2037-03-08T03:00:00-07:00 [2037-03-08T10:00:00Z] -08:00 -> -07:00 {2120119200}
2037-11-01T01:00:00-08:00 [2037-11-01T09:00:00Z] -07:00 -> -08:00 {2140678800}
2038-03-14T03:00:00-07:00 [2038-03-14T10:00:00Z] -08:00 -> -07:00 {2152173600}
2038-11-07T01:00:00-08:00 [2038-11-07T09:00:00Z] -07:00 -> -08:00 {2172733200}
2039-03-13T03:00:00-07:00 [2039-03-13T10:00:00Z] -08:00 -> -07:00 {2183623200}
2039-11-06T01:00:00-08:00 [2039-11-06T09:00:00Z] -07:00 -> -08:00 {2204182800}
2040-03-11T03:00:00-07:00 [2040-03-11T10:00:00Z] -08:00 -> -07:00 {2215072800}
2040-11-04T01:00:00-08:00 [2040-11-04T09:00:00Z] -07:00 -> -08:00 {2235632400}
2041-03-10T03:00:00-07:00 [2041-03-10T10:00:00Z] -08:00 -> -07:00 {2246522400}
2041-11-03T01:00:00-08:00 [2041-11-03T09:00:00Z] -07:00 -> -08:00 {2267082000}
2042-03-09T03:00:00-07:00 [2042-03-09T10:00:00Z] -08:00 -> -07:00 {2277972000}
2042-11-02T01:00:00-08:00 [2042-11-02T09:00:00Z] -07:00 -> -08:00 {2298531600}
2043-03-08T03:00:00-07:00 [2043-03-08T10:00:00Z] -08:00 -> -07:00 {2309421600}
2043-11-01T01:00:00-08:00 [2043-11-01T09:00:00Z] -07:00 -> -08:00 {2329981200}
2044-03-13T03:00:00-07:00 [2044-03-13T10:00:00Z] -08:00 -> -07:00 {2341476000}
2044-11-06T01:00:00-08:00 [2044-11-06T09:00:00Z] -07:00 -> -08:00 {2362035600}
2045-03-12T03:00:00-07:00 [2045-03-12T10:00:00Z] -08:00 -> -07:00 {2372925600}
2045-11-05T01:00:00-08:00 [2045-11-05T09:00:00Z] -07:00 -> -08:00 {2393485200}
2046-03-11T03:00:00-07:00 [2046-03-11T10:00:00Z] -08:00 -> -07:00 {2404375200}
2046-11-04T01:00:00-08:00 [2046-11-04T09:00:00Z] -07:00 -> -08:00 {2424934800}
2047-03-10T03:00:00-07:00 [2047-03-10T10:00:00Z] -08:00 -> -07:00 {2435824800}
2047-11-03T01:00:00-08:00 [2047-11-03T09:00:00Z] -07:00 -> -08:00 {2456384400}
2048-03-08T03:00:00-07:00 [2048-03-08T10:00:00Z] -08:00 -> -07:00 {2467274400}
2048-11-01T01:00:00-08:00 [2048-11-01T09:00:00Z] -07:00 -> -08:00 {2487834000}
2049-03-14T03:00:00-07:00 [2049-03-14T10:00:00Z] -08:00 -> -07:00 {2499328800}
2049-11-07T01:00:00-08:00 [2049-11-07T09:00:00Z] -07:00 -> -08:00 {2519888400}
2050-03-13T03:00:00-07:00 [2050-03-13T10:00:00Z] -08:00 -> -07:00 {2530778400}
2050-11-06T01:00:00-08:00 [2050-11-06T09:00:00Z] -07:00 -> -08:00 {2551338000}

Here's the Chronos code that generates the list of offset transitions:
  | transition prevOffset printPolicy |
printPolicy := ChronosPrintPolicy iso8601.
transition := Timepoint year: 1881 day: 1 timeZone: #'America/Los_Angeles'.
[prevOffset := transition offset.
transition := transition nextOffsetTransitionDateAndTimeIfNone: [].
transition == nil or: [transition year > 2050]]
cr; show: transition printString;
tab; show: ' ['; show: transition asUT % printPolicy; show: ']';
tab; show: prevOffset timeZoneOffsetPrintString;
show: ' -> '; show: transition offset timeZoneOffsetPrintString;
tab; show: ' {';
show: (transition secondsSince: ChronosSystemClock unixEpoch) printString;
show: '}'].


Why don’t calendars do Time Zones?

Jim Phelps asks (2006-01-18) "Why don’t calendars do Time Zones?"

He laments "My laptop and my palm both understand Time Zones. I understand Time Zones. Why don’t my calendar applications (Oracle’s Calendar and the Palm Calendar in the handheld) understand Time Zones?"

Jim has the following "simple" requests:

  1. When I create an appointment I should be able to mark the Time Zone for the appointment.

  2. I should also be able to make appointments that are Time Zone neutral - not tied to a Time Zone.

  3. My clients (Palm and Desktop and Web) should all understand Time Zones and should be able to shift the alarms to compensate for my changes in Time Zone.

Here's how Jim would use such functionality, were it only available:

  • If I get an invite to join a conference call at 11AM EST, I could just enter that time without adjusting for my local time zone. Same with UTC time.

  • If I changed time zones (say fly from Madison to San Francisco), my alarms would change to be appropriate. As it is now, if I fly to California, I need to keep track of the fact that the 10AM meeting is really a[t] 10AM Central time so I need to set an alarm 2 hours earlier. But I can’t do a global change because some things might be dinners in California so they need to stay on Pacific time.

Of course, Jim's not the only one whose Use Cases aren't well satisfied by most current applications and/or date time libraries. For example, a few years ago, some date/time Use Cases were posted on, because Zope's date/time functionality was seen as unsatisfactory. And on BoingBoing, there was the rant "Extended iCal rant from a timezone warrior," whose basic complaint resembles Jim's. There was also recently a discussion on Bugzilla where some of the same issues and concerns were raised.

Here are the key requirements that can be abstracted from the aforementioned discussions/rants:
  • It must be possible to associate each point-in-time value with a time zone that may or may not be the same as the time zone associated with other point-in-time values.
  • It must be possible to specify a point-in-time without reference or association to any particular time zone. (Examples: The point-in-time that specifies the first moment of 2008 (for any and all time zones,) the annual date on which a person's birthday is celebrated, the list of non-business days of the US Federal government, the date on which a person must have been born in order to legally purchase alcohol today.)
  • Point-in-time values must either know, or be able to derive, both their local time and their Universal Time.
  • It must be possible to convert point-in-time values from one time zone to another.
  • The same point-in-time value must be able to act as though it is associated with ("local to") a different time zone in different contexts (e.g., the possibly-different local time zone of different users at the same time, and also the local time zone of the same user at different times, even when the user's local time zone changes as he travels from one location to another.)
  • Point-in-time values should provide both sufficient sub-second resolution and sufficient range (from earliest to latest representable value.)
  • Point-in-time values should provide appropriate granularities--timestamps should span a reasonably small sub-second duration, but dates should span a calendar day (and not be sub-second-resolution timestamps that happen to specify the first moment of the day.)
  • Point-in-time values must be immutable so that changes to their value don't invalidate the logic that uses them (e.g., they must be useable as dictionary keys.)
  • Adding any combination of some number of days, months and years to a point-in-time value should result in a new point-in-time value that number of days/months/years distant--but having the same civil time of day, regardless of any DST transitions that may have occurred.
  • It must be possible specify partial/recurring dates and times (e.g., "every/any day at 5pm," "the last Sunday of October every/any year.")

I was especially interested in what one of the Zope developers had to say in response to the Zope Use Cases posted by the general public (spelling and punctuation as in the original):

"I find all of that very allarming.

Do people want the datetime object solve all this use cases out of the box? I hope that they are only samples of applications and that people agree that they will have to do a little work by theimself.

It is already difficult to find a straightforward interface for basic operations, if we wait to have an universal datetime type, we will never have it before Python 48.12b1 release.

So please, go for a minimal API, and let people play with the type and discover the better way to do elaborated stuff.

By the way from the tz database README file at: you can't guess a time zone from a time-zone offset and a daylight saving flag.

So I think that a full and cross-platform timezone support is just a wonderful dream. But if you can prove me that I'm false, with an actual implementation ..."

I'm quite sure that many programmers would have a similar reaction: They'd be highly alarmed. Well, tough. People don't care how you solve their problems, they just want them solved. A solution that doesn't work right can be worse (or no better than) not having any solution at all.

We've had "a minimal API" for date/time computations available in just about every programming language and operating system for decades now--but the requests, complaints and rants shown above are from recent times, not from decades past. It's almost universally true that programming languages, operating systems and applications either don't handle dates/times at all, or don't do so correctly and consistently, and don't satisfy most of the requirements discussed above.

"Do the simplest thing that could possibly work" is not a license to provide incomplete and/or incorrect functionality. Real use cases that are commonly encountered are not being satisfied. The first step to a cure is to admit there's a problem.

Dates and times are not simple. Not at all. They're a relatively hard problem. The truth is, dates and times are too hard for most programmers to handle correctly on their own--which is precisely why they don't do it, and instead attempt to justify their failure by misapplying design principles. And that's why the "provide the simple stuff, and let the application coders solve the hard problems" approach won't work. It doesn't work in other domains, either--not in the past, not now, and probably not ever.

The "let them do it themselves" approach is about as wise as letting each application programmer code his own number classes, his own collection classes, his own filesystem, his own garbage collection engine, his own virtual memory subsystem, his own graphics library and GUI framework, his own web/application server--and in his spare time, develop his own programming language and compiler. If you really feel that a date/time library that actually gets the job done would be just too complex, then to be consistent, you would have to raise the same objection to all the other tools that programmers don't do themselves anymore (because the problems are hard, and most programmers will take unwise shortcuts, or make serious errors, if they have to do it themselves.)

As time has gone by, we've gone from machine language, to assembly language, to procedural languages, to functional languages, to object-oriented languages. We've gone from no operating system, to reusable, statically-linked code libraries, to dynamically-linked code libraries, to run time systems, to basic operating systems, to operating systems with virtual memory, to operating systems with GUIs. We've gone from punched cards to Microsoft Word, and from the abacus to Microsoft Excel.

Does anyone see a pattern here? Yes, you have to walk before you can run. But we've been crawling around trying to avoid actually dealing with dates and times in all their glory for far too long now. It's time to advance to the next level. So, to the programmers of the world, I say: Admit it. Admit that you're not satisfying the real date/time use cases.

As for an actual implementation of a date/time library that satisfies the requirements we've been discussing, it happens that there is at least one: The Chronos Date/Time Library. Of course, it's a date/time library, not a calendaring/scheduling application, so it would be more accurate to say it makes it much easier to write applications with just about all of the requested features. Yes, applications do need to take some responsibility for their own particular use cases.

What are the features of Chronos that satisfy (or greatly help to satisfy) the requirements discussed above? They are as follows:

  1. Chronos uses the Olson Time Zone Database, so it knows about all the world's time zones--including historical information. For example, Chronos knows, and is able to correctly handle, all the following facts:
    • Most (but not all!) locations in North America have been switching from standard time to daylight saving time on the first Sunday of April each year, from 1987 through 2006--but starting in 2007, most North American locations will switch from standard time to daylight saving time on the second Sunday of March.
    • All the countries in the European Union modernly transition to and from daylight saving time at the same moment in Universal Time--unlike the case in North America, where all zones with the same offset transition to/from daylight saving time at the same local time, but at a different moment in Universal Time.
    • All of India uses the same time zone offset, does not observe daylight saving time, and uses an offset of 5.5 hours east of Universal Time.
    • In Australia, South America, New Zealand and Africa, daylight saving time, if it is observed at all, is observed during the Southern Hemisphere's summer (for example, from September to April.)
    • During World War II, several countries were on "daylight saving time" all year round for several years in a row (in the US, this was called "War Time," and was abbreviated as "EWT," "CWT," "MWT" and "PWT.")
    • For the years 1921 and 1922 only, Moscow started the year with an offset of 3 hours, transitioned to an offset of 4 hours on 1920-02-24T23:00 and 1921-02-24T23:00, transitioned to an offset of 5 hours on the 79th day of the year (different dates and day-of-the-week each year,) transitioned back to an offset of 4 hours on the 244th day of the year, and then transitioned back to an offset of 3 hours on the 274th day of the year (so there were 4 offset transitions and 3 different offsets each year.)

  2. In addition to the predefined time zones that come from the information provided by the Olson Time Zone Database, Chronos permits you to define your own time zones--which can be as simple as "-5 hours asTimezone" or as complex as any of the cases described in the preceding bullet item. Or you can easily construct a Chronos time zone from either a POSIX time zone rule literal or from the information in the Windows registry--and it will behave identically to its UNIX or Windows counterpart.

  3. The Chronos Time Zone Repository (which is generated from the Olson Time Zone Database) is deployed separately and independently from the Chronos codebase. Either can be changed without any need to redeploy the other--and even already-running applications can see and use a newly-deployed version of the time zone repository. And both Chronos and the Chronos Time Zone Repository are available for Windows, Mac, Unix and Linux--so your applications will not only run unchanged in all those environments, but will exhibit identical date/time behavior.

  4. Chronos point-in-time values can be associated with ("bound to" in Chronos terminology) a particular time zone. Or, they can be bound to a proxy time zone that dynamically refers to a different time zone at different times or in different contexts (so that the associated point-in-time's local time changes dynamically whenever the proxy time zone is changed to have a different time zone as its referent.) Or, Chronos point-in-time values can be bound to a special time zone that Chronos refers to as "nominal time." Nominal time represents the concept of "any time zone," or "local time in some unspecified context, or in any and all contexts simultaneously."

  5. Chronos point-in-time values that are bound to a specific time zone or to a proxy time zone (and so aren't bound to nominal time) are said to be invariant to Universal Time. Chronos point-in-time values that are bound to nominal time are said to be invariant to nominal time. Point-in-time values that are invariant to Universal Time keep the moment in time that they represent in Unversal Time as their semantic invariant. Point-in-time values that are invariant to nominal time keep the moment in time that they represent in nominal time (their "local time") as their semantic invariant. In other words, two points-in-time that are invariant to Universal Time are equal when they represent the same moment in Universal Time, regardless of the moment they nominally specify in their local time zone (the one to which they are bound.) But a point-in-time that is invariant to nominal time is equal to any other point-in-time that specifies the same nominal (local) time. So the following expressions both evaluate to true:
    • (Timepoint 
      year: 2007 month: 2 day: 3
      hour: 10 minute: 0 second: 0
      timeZone: -8 hours)
      = (Timepoint
      year: 2007 month: 2 day: 3
      hour: 13 minute: 0 second: 0
      timeZone: -5 hours)
      "10 am in California is the same moment
      in Universal Time as is 1pm in New York"
    • (Timepoint 
      year: 2007 month: 2 day: 3
      hour: 13 minute: 0 second: 0
      timeZone: Timezone nominal)
      = (Timepoint
      year: 2007 month: 2 day: 3
      hour: 13 minute: 0 second: 0
      timeZone: -5 hours)
      "1 pm nominal time is 1pm local time,
      regardless of time zone"

  6. Chronos point-in-time values that are invariant to Universal-Time internally store their value in Universal Time, but report their year, month, day, hour, minute and second according to the equivalent local time in the time zone with which they are associated. Also, the local time values for their year, month and day-of-month are cached (lazily computed when needed--it's an expensive computation.)

  7. Chronos point-in-time values can easily (and efficiently) be converted from any time zone to any other:
    year: 2007 month: 2 day: 3
    hour: 13 minute: 0 second: 0
    timeZone: 'Pacific/Honolulu') >> #'Asia/Katmandu'
    results in 2007-02-04T04:45:00+05:45 (and yes, Asia/Katmandu actually does have an offset of 5 hours 45 minutes.)

  8. Chronos point-in-time values have no limits (other than available memory on your computer) with respect to the range of representable dates--a feature that derives mostly from the fact that Chronos is implemened in Smalltalk--although, even if the implementation language had limited the design to using nothing but 32-bit signed integers, the way Chronos internally represents point-in-time values would still have supported a range of +/- 6 million years for timestamps (and +/- 2 billion years for dates.) Chronos also provides a special value that represents the infinite past, and another that represents the infinite future.

  9. Chronos point-in-time values are actually time intervals, as explained in the Chronos blog entry Chronos 101: "Points" in Time. Chronos points-in-time that are meant to represent dates have a temporal extent (and hence resolution) of one calendar day. Chronos points-in-time that are meant to be used as timestamps have a temporal extent (and hence resolution) of one nanosecond. In addition to these two common cases (one optimized for dates, the other for timestamps,) Chronos provides general Timeperiod values, which can start at any point in time, and can have any temporal extent/duration.

  10. Chronos point-in-time, durational and time interval values are all immutable.

  11. Chronos handles date/time arithmetic correctly, satisfying both civil and scientific/technical use cases. Adding a day results in the same civil time of day on the next calendar day.

  12. Chronos provides a variety of classes for representing partial/recurring dates--including the time-of-day without any associated date, and the month/day without any specified year. You can even construct a value that specifies "the first Tuesday of November, every fourth year modulo 4."

And there's yet more. If you're interested, you can peruse the Chronos web site, browse the Chronos blog, or read the "Chronos 101" tutorials, of which the following have been published so far:

So, to answer Jim's original question, calendar applications don't understand time zones because most people, including software developers, programming language library creators and programming language designers don't understand time zones. Or in some cases, they understand them well enough, but decide (for whatever reason) that full and correct time zone behavior is more work than they want to take on. Fortunately, that unwillingness to tackle the date/time domain comprehensively is not universal.

Physicists find way to 'see' extra dimensions

Perhaps String Theory may be testable in practice, after all:

Physicists find way to 'see' extra dimensions from

Peering backward in time to an instant after the big bang, physicists at the University of Wisconsin-Madison have devised an approach that may help unlock the hidden shapes of alternate dimensions of the universe.


Microprinting Technique for Patterning Single Molecules

Microprinting Technique for Patterning Single Molecules from

A new process for creating patterns of individual molecules on a surface combines control of self-assembled monolayers (SAMs) and a soft lithography technique known as microcontact printing. Scientists use the process, known as "microcontact insertion printing" to build surfaces that have molecules with specific functions inserted at known intervals on a surface.



Maxwell's Demon

Nano machine of the future captures great scientist’s bold vision from

An idea conceived by one of the world's greatest scientists nearly 150 years ago has finally been realised with a tiny machine that could eventually lead to lasers moving objects remotely.


This is actually a rather significant advance scientifically, although it's technological implications may take a while to become evident. What matters here is that this result is an existence proof that a new technological paradigm that many have forecasted (but which many have also doubted) will actually be possible in practice. It's hard to argue against reproducible results.