Version 18 of clock

Updated 2002-12-03 17:18:34

See http://purl.org/tcl/home/man/tcl8.4/TclCmd/clock.htm for the formal man page. Beyond that, try the %Q format:

 % clock format [clock scan now] -format %Q
 Stardate 56657.7

 From news:comp.lang.tcl, I see:
 Date: Mon Mar 19 15:41:16 EST 2001
 From: Jeff Hobbs <[email protected]>
 Organization: ActiveState - Programming for the People


 [email protected] wrote:
 Is there a way to do the following by using the clock command:
 If I have a date in the future, for example Mar 26, 2001
 I need to find out what the date for that Saturday is. (Sat Mar 31,  2001)

 Apr 30, 2001 = Sat May 5, 2001
 Mar 28, 2001 = Sat May 5, 2001

 (hobbs) 50 % clock format [clock scan "Saturday" \
        -base [clock scan "Apr 30, 2001"]]
 Sat May 05 00:00:00 Pacific Daylight Time 2001
 (hobbs) 51 % clock format [clock scan "Saturday" \
        -base [clock scan "Mar 28, 2001"]]
 Sat Mar 31 00:00:00 Pacific Standard Time 2001

You can format relative time in seconds to h:m:s format. Just make sure you pretend to be in Greenwich( -gmt 1), otherwise your local timezone may be added. (RS)

  clock format 711 -format %H:%M:%S -gmt 1
  01:11:51

rmax: Is there any chance to tell [clock format] to use another timezone than local or GMT?

 patthoyts:
 % set env(TZ) GMT ; clock format [clock seconds] 
 Wed Jan 30 16:07:47 GMT 2002 
 % set env(TZ) GMT+2 ; clock format [clock seconds] 
 Wed Jan 30 14:07:52 GMT 2002 

Traditional degrees: clock format can be put to un-timely uses. As degrees especially in geography are also subdivided in minutes and seconds, how's this one-liner for formatting decimal degrees:

 proc dec2deg x {concat [expr int($x)]��° [clock format [expr round($x*3600)] -format "%M' %S\""]}

An additional -gmt 1 switch is needed if you happen to live in a non-integer timezone. (RS)


Want to format the modification time of a specific file? Try

 clock format [file mtime "/path/to/my/file"]

where you replace /path/to/my/file with the path you want. Or replace it with a variable containing the path.


To get back, from clock, yesterday's date, use

 clock format [clock scan yesterday]

The list of time zones handled by Tcl is:

  • adt - Atlantic Daylight
  • ahst - Alaska-Hawaii Standard
  • ast - Atlantic Standard
  • at - Azores
  • bst - British Summer
  • bt - Baghdad, USSR Zone 2
  • cadt - Central Australian Daylight
  • cadt - Central Australian Daylight Time
  • cadt - Central Australian Standard Time
  • cast - Central Australian Standard
  • cat - Central Alaska
  • cct - China Coast, USSR Zone 7
  • cct - China Coast, USSR Zone 7
  • cdt - Central Daylight
  • cest - Central European Summer
  • cet - Central European
  • cst - Central Standard
  • dst - DST on (hour is ignored)
  • eadt - Eastern Australian Daylight
  • eadt - Eastern Australian Daylight Time
  • eadt - Eastern Australian Standard Time
  • east - Eastern Australian Standard
  • edt - Eastern Daylight
  • eet - Eastern Europe, USSR Zone 1
  • est - Eastern Standard
  • fst - French Summer
  • fwt - French Winter
  • gmt - Greenwich Mean
  • gst - Guam Standard, USSR Zone 9
  • gst - Guam Standard, USSR Zone 9
  • hdt - Hawaii Daylight
  • hst - Hawaii Standard
  • idle - International Date Line East
  • idlw - International Date Line West
  • ist - Indian Standard
  • it - Iran
  • jst - Japan Standard, USSR Zone 8
  • jt - Java (3pm in Cronusland!)
  • mdt - Mountain Daylight
  • mest - Middle European Summer
  • met - Middle European
  • mewt - Middle European Winter
  • mst - Mountain Standard
  • ndt - Newfoundland Daylight
  • nft - Newfoundland
  • nst - Newfoundland Standard
  • nt - Nome
  • nzdt - New Zealand Daylight
  • nzst - New Zealand Standard
  • nzt - New Zealand
  • pdt - Pacific Daylight
  • pst - Pacific Standard
  • sst - Swedish Summer
  • swt - Swedish Winter
  • uct - Universal Coordinated Time
  • ut - Universal (Coordinated)
  • utc
  • wadt - West Australian Daylight
  • wast - West Australian Standard
  • wat - West Africa
  • wet - Western European
  • ydt - Yukon Daylight
  • yst - Yukon Standard
  • zp4 - USSR Zone 3
  • zp5 - USSR Zone 4
  • zp6 - USSR Zone 5

In the year 2002, the first week reported by %w is 00. To get more natural numbers starting from 1 (and without leading zero), use

 expr [scan [clock format [clock sec] -format %W] %d]+1 ;#RS

This was not the case in the years {1973 1979 1990 1996 2001 2007 2018 2024 2029 2035}, a distance sequence of 6-5-6-11.., where the first week was 01... Hence this cleanup routine, where Jan 1 is always in week 1:

 proc week {date} {
   set week [scan [clock format $date -format %W] %d]
   set year [clock format $date -format %Y] 
   if {[lsearch {
        1973 1979 1990 1996 2001 2007 2018 2024 2029 2035
        } $year] < 0} {
        incr week 
   }
   set week
 } ;# RS - but better just use %V:

Kevin Kenny wrote on this question in the comp.lang.tcl newsgroup on 2001-01-07, so in week 01 ;-): The format group, %V, yields the ISO8601 fiscal week number. It's inexplicably missing from the documentation in 8.3; this has been fixed in 8.4.

By the way, lots of companies in the US (my employer is NOT one) use a fiscal week numbering system where week 1 begins on the first Sunday of the year rather than on the Monday before the first Thursday.


NEM - From a question in comp.lang.tcl and a session on the chat, here is a proc for getting the start and end days of a week given a week number (0-51):

 proc dates {date} {
     set date [clock scan "$date weeks" -base [clock scan "01/01/2002"]]
     set st [clock scan "sunday" -base [expr {$date - 436800}]]
     set end [clock scan "saturday" -base $date]
     return [list [clock format $st] [clock format $end]]
 }

Thus,

 dates 48

gives

 {Sun Dec 01 00:00:00 GMT 2002} {Sat Dec 07 00:00:00 GMT 2002}

NEM - After some heckling on comp.lang.tcl for not allowing you to specify a year, or what day the week starts on, here is an improvement:

 proc dates {date {year now} {day "Sunday"}} {
      set days [list sun mon tue wed thu fri sat]
      set day [string tolower [string range $day 0 2]]
      if {[string equal $year now]} {
          set year [clock format [clock scan now] -format %Y]
      }
      set date [clock scan "$date weeks" -base [clock scan "01/01/$year"]]
      set st [clock scan $day -base [expr {$date - 436800}]]
      set endday [lsearch $days $day]
      set endday [expr {($endday - 1) % 7}]
      set endday [lindex $days $endday]
      set end [clock scan $endday -base $date]
      return [list $st $end]
 }

It does all the necessary magic. It also returns the numbers rather than pre-formatting them, as this is more flexible. One improvement would be to allow specifying the end day of the week as well (for working weeks, etc). You could do this with an extra parameter, and only calculating the endday if it was not set.


Tcl syntax help - Arts and crafts of Tcl-Tk programming - Date and Time Issues - Category Command - Reworking the clock command