Version 19 of Clock and daylight saving time corrections

Updated 2007-02-21 10:15:58

Arjen Markus (24 august 2005) The [clock] command is a wonderful instrument, despite all its quirks, if you need to do date/time computations. I ran into one quirk the other day that is not the fault of the implementation, but rather of the complicated calendar we use in today's world: daylight saving time.

Let me explain my problem:

  • I had a starting date in october and I wanted to know the end date after N spring-neap cycles (in my approximation: 15 days and 6 hours).
  • I used the clock command to do the computation and got some date in january, 7 o'clock as the stop date/time.

Then I realised that I had crossed the date where the daylight saving time correction changes. By using the option -gmt 1 you can avoid these complications.

Here is an illustration of the effect:

 # Daylight saving problems
 #
 # No care for daylight saving time corrections ...
 #
 set day1 [clock scan "2005-10-01"]
 set day2 [clock scan "2005-11-01"]
 set number_days [expr {($day2-$day1)/86400.0}]
 puts "Number of days: $number_days"

 # Option: -gmt 1
 #
 set day1 [clock scan "2005-10-01" -gmt 1]
 set day2 [clock scan "2005-11-01" -gmt 1]
 set number_days [expr {($day2-$day1)/86400.0}]
 puts "Number of days: $number_days"

The result (Tcl 8.4):

 Number of days: 31.0416666667
 Number of days: 31.0

Of course, it depends on what you want to achieve, if you need this option or not. Date/time computations are simply very complicated.


LV A friend sent me this pointer [L1 ] which discusses the fact that a number of countries have been, and continue to, make changes in the way DST is calculated. Does anyone know whether Tcl is tracking these kinds of adjustments?

MG As far as I know, all Tcl's time functions are platform-dependent, so as long as the underlying OS knows about them, Tcl will too.

LV Certainly in Tcl 8.5, there is now a large amount of timezone information. I just don't know enough about those files to know whether Tcl software has to change, given that there seems to be discussion of things like java changes. Just was curious.

MG tends to forget 8.5 - my comments were aimed more at 8.4. I'm not sure how the additional things in 8.5 work.

KBK answers LV's question with 'Yes.' Tcl is indeed tracking time zone changes, and you can expect that it will continue to do so. Unlike Windows, it also returns correct historical time information, at least back to 1970 or so. That said, on most Unix systems you will also need to keep 'zoneinfo' up to date; it's common to omit Tcl's tzdata from an installation if the local machine has the equivalent in 'zoneinfo'. Also, the ':localtime' time zone does whatever the underlying OS and C library do.

Knowing what part of the world Larry comes from, I must caution that it does not have correct information for certain West Virginia counties from the 1960's - the rules for Daylight Saving Time there were both controversial and contradictory. I doubt that very many people there actually knew what time it was in the next town over. I certainly doubt that they changed their watches half-a-dozen times in an hour-long bus ride simply because the different towns had different rules. (If memory serves, some had yet to adopt Standard Time and set the courthouse clock to local mean solar time!)

LV Amusingly enough, I lived in WV during that time period, and know EXACTLY the situation to which Kevin refers.

The article at [L2 ] includes a section titled Inconsistent use in the U.S. which makes reference to the situation - note that I lived about 5 seconds off Route 2, about 15-20 minutes south of the bus route mentioned...


LV If the date occurs before "1970 or so" , does Tcl default back to the OS's zoneinfo or whatever? Or does it just not try?

I understand that the timezone info isn't granular enough to handle the special cases of a particular county or town which decides not to observe DST.

KBK Your understanding is incomplete. Arthur Olson, from whom I get the data, makes an effort to keep the timezone info granular enough. Indiana, for instance, is divided into locales,

  • 'America/Indiana/Indianapolis',
  • 'America/Chicago' (these two cover most of the cases),
  • 'America/New_York' (Dearborn and Ohio Counties),
  • 'America/Kentucky/Louisville' (Clark, Floyd and Harrison Counties),
  • 'America/Indiana/Vincennes' (Daviess, Dubois, Knox, Martin, Perry, and Pulaski Counties),
  • 'America/Indiana/Marengo' (a township in Crawford County),
  • 'America/Indiana/Petersburg' (Pike County),
  • 'America/Indiana/Knox' (Starke County), and
  • 'America/Indiana/Vevay' (Switzerland County).

Generally speaking, a locale that has, since 1970, followed the same rules as a better-known place will have that better-known place's rules applied to dates before 1970. Thus, a resident of Moundsville, West Virginia, will see his clock keeping the Daylight Saving Time rules that were in effect for New York City.


LV Is there a way to write Tcl code that could be used to answer the question "for timezone ABC, on a particular date and time, was daylight savings time in effect"?

LV Later... I thought about using

 clock format now -format {Z} -timezone $whatever

and comparing the timezone against a known value. Alas, that fails, for example, in Melbourne Austraila, where the 3 letter abbreviation for non-daylight is EST - Eastern Standard Time and for daylight savings is EST - Eastern Summer (Daylight) Time.

Yuck.

LV Even later - I tried to poke inside Tcl 8.5's clock.tcl , to invoke the internal pieces of clock to get at the date and time parsing code, but so far, I've not success getting the right pieces to play nicely with one another.

KBK For some locales and times, the question isn't even meaningful. What do you want it to return for a locale that has advanced its clock two hours (e.g. Israel right after independence, or Newfoundland in 1988)? For a locale that temporarily reverts to solar time from Standard Time (Detroit in 1902)? For things like 'Eastern War Time'? You can use the %z format group to get the time zone's offset from Greenwich, and compare that against a known value, I suppose. If the intent of your question was to determine, "what is the offset from Greenwich in a particular locale on a particular date and time?" then %z is surely the answer. (Caveat: 8.5 only!)


Category Date and Time - Category Example