Monday, October 10, 2011

Version 1.1.2 (stable) of the Time2 Library supports ISO 8601

A new version of the Time2 Library is available at http://time2.sourceforge.net/ and http://agent.ch/timeseries/t2/.

This new release brings improved support for the representation of dates and times as defined by the ISO 8601:2004 standard. Basic and extended date and time strings are allowed. In the extended format, the current time, as I'm writing, is represented as 2011-10-10T12:42:53Z. The Z indicates UTC time. The same time in the basic format is written 20111010T124253Z. Because time zones and daylight savings time are irrelevant in the Time2 Library, the Z letter can be omitted.

When using the extended format, the T separating date and time can be replaced with a blank. So the example can also be represented as 2011-10-10 12:42:53, arguably nicer on the eye. This more natural format is used by Time2.toString().

Local times can be specified using a time zone offset. For example, I am writing this from Switzerland, where the time zone is CEST, 2 hours ahead of UTC. In the ISO 8601:2004 standard, this can be written 2011-10-10T14:42:53-02.

There are some exotic features in the ISO 8601 standard. Some of them, like leap seconds or the use of hour 24 for midnight, are supported. Others, like week dates and ordinal dates are not.

Monday, October 3, 2011

Why make it complicated when you can make it impossible?

Dates and times may be quite familiar but when you need to do something with them, especially in software, you are confronted with a glorious mess. To get an idea, spend a few moments on the subject in Wikipedia, Google, or the Java documentation. Here are some of the things you will find.

There is no year zero, except when there is one...

If you are a historian, there is no year 0. The year AD 1 immediately follows the year 1 BC (see Anno Domini in Wikipedia). On the other hand, if you are an astronomer, there is a year 0 (see Astronomical year numbering in Wikipedia). In the ISO 8601 international standard for representing dates and times, years are represented by four digits from 0000 to 9999. So, if you are following the standard, there is a year 0. But with XML, there is a problem. XML time was inspired by an early version of ISO 8601 and disallows year 0. Fortunately, this is likely to change in the future to agree with more recent versions of ISO 8601. See XML Schema Part 2: Datatypes Second Edition from W3C.

If you have an ancestor born on October 10, 1582, stick to the ISO standard!

In some countries, October 15, 1582 immediately followed October 4 (see Gregorian calendar in Wikipedia). The ISO 8601 international standard states that every date must be consecutive and that dates before October 15 1582 can be used by mutual agreement when exchanging information. So, under the standard, there would have been no hole between October 4 and 15, 1582, and your ancestor would have been born on an existing day.

Some minutes have 61 seconds

Nowadays, time is measured with atomic clocks (see Coordinated Universal Time (UTC) in Wikipedia). Atomic time does not exactly match the earth's rotation and a so-called leap second can be added or substracted from UTC at the end of June or December to avoid the discrepancy growing beyond a second. So, minutes have 59, 60, or 61 seconds. For more information on leap seconds, consult Date and Time on the Internet: Timestamps (RFC3339) at the IETF, and Leap Seconds at the US Naval Observatory. Note because it is not known long in advance when one will be introduced, leap seconds cannot be programmed in software.

Avoid the Dutch calendar between 1909 and 1937

When using local time, time zones and daylight savings time are issues to consider. The fact that most methods of the Java Date class are deprecated shows that getting such things right is not straightforward. Calendar and Joda Time are better, but their complexity can be seen as further proof that dates and times are messy. The ISO 8601 standard attempts to sidestep the whole question by not supporting time zones at all. Time is either local or expressed as an offset from UTC. But even then, there is a problem. The offset used by the ISO standard is in hours and minutes. But there are known cases where this is not sufficient. Here is a quote from RFC 3339:

1937-01-01T12:00:27.87+00:20

This represents the same instant of time as noon, January 1, 1937,
Netherlands time. Standard time in the Netherlands was exactly 19
minutes and 32.13 seconds ahead of UTC by law from 1909-05-01 through
1937-06-30. This time zone cannot be represented exactly using the
HH:MM format, and this timestamp uses the closest representable UTC
offset.

The Y2.038K problem

If you thought the year 2000 problem was interesting, then you will like 2038, when the Unix clock will wrap around. Such problems and many facts about dates and times are documented in Gilbert Healton's The Best of Dates, The Worst Of Dates.

Time and the Time2 Library

When I wrote the Time2 Library, I was looking for something lightweight to represent dates and the time of day. Dates and times are only a small part of what the library does and I did not want to spend too much time on time. But I was not happy with Java's Date because it is mostly deprecated. Other possible solutions were not exactly lightweight. So I decided to write my own solution and to keep it simple, with the requirement to implement part of the ISO 8601 specification (ignoring durations and intervals): all years between 0000 and 9999 valid, no hole in October 1582, no support for time zones and daylight savings time, but tolerance for time zone offsets and leap seconds (the last two things are still on the to-do list.)