Version 51 of cal

Updated 2007-05-02 17:54:31 by suchenwi

Richard Suchenwirth 2007-04-26 - A little fun project while waiting for a lengthy build: the following code produces a string with the calendar of one month (as a subset of what the Unix command of same name does), e.g.

 % cal April 2007
     April 2007
 Su Mo Tu We Th Fr Sa
  1  2  3  4  5  6  7
  8  9 10 11 12 13 14
 15 16 17 18 19 20 21
 22 23 24 25 26 27 28
 29 30

Here's the code, densely textured :^)


 proc cal {{month {}} {year {}}} {
    if {$month eq ""} {set month [clock format [clock sec] -format %B]}
    if {[llength $month] > 1} {
      set res {}
      foreach m $month {
        append res [cal $m $year]\n\n
      }
      return [string trimright $res]
    }
    if {$year eq ""}  {set year [clock format [clock sec] -format %Y]}
    set res "     $month $year\n Su Mo Tu We Th Fr Sa\n"
    set weekday [clock format [clock scan "1 $month $year"] -format %w]
    append res  [string repeat "   " $weekday]
    scan [clock format [clock scan "1 $month $year"] -format %m] %d decm
    set maxd [numberofdays $decm $year]
    for {set d 1} {$d <= $maxd} {incr d} {
        append res [format %3d $d]
        if {[incr weekday]>6} {append res \n; set weekday 0}
    }
    set res
 }
 proc numberofdays {month year} {
    if {$month==12} {set month 1; incr year}
    clock format [clock scan "[incr month]/1/$year  1 day ago"] \
        -format %d
 }
 # Test:
  catch {console show}
  catch {wm withdraw .}

  puts [ cal Jan 2007 ]
  puts "\n"
  puts "List of month:\n [ cal {Apr May} ]\n"
  puts "Current month:\n [ cal "" 2007 ]"
  puts "Default is the current month:\n [ cal ]"

Someone else might want to take a look at the above code and add the appropriate localisation/internationalizations (so that the day and month names are displayed in the local language preferences, etc.


wdb simply great!


MJ - Added that if the month is a list of month names, the result will be a calender for all the months.

 % cal {Apr May}
      Apr 2007
  Su Mo Tu We Th Fr Sa
   1  2  3  4  5  6  7
   8  9 10 11 12 13 14
  15 16 17 18 19 20 21
  22 23 24 25 26 27 28
  29 30

      May 2007
  Su Mo Tu We Th Fr Sa
         1  2  3  4  5
   6  7  8  9 10 11 12
  13 14 15 16 17 18 19
  20 21 22 23 24 25 26
  27 28 29 30 31

HJG Added a little test.


LV Added the output of the default call.

HOWEVER, one behavior missing from the above routine is the behavior if one supplies only a year:

 unable to convert date-time string "1 2007 2007"
    while executing
 "FreeScan $string $base $timezone $locale"
    (procedure "::tcl::clock::scan" line 70)
    invoked from within
 "clock scan "1 $month $year""
    (procedure "cal" line 12)
    invoked from within
 "cal 2007 "
    invoked from within
 "puts "Year calendar output:\n [ cal 2007 ]""
    (file "/tmp/cal.tcl" line 37)

RS Wrong call.


Category Date and Time