Un petit calendrier

 

Richard Suchenwirth 2007-03-26 - Voilà un petit programme qui produit une chaine représentant le calendrier d'un mois, comme ça:

     March 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

Il est fait suivant le modèle "cal" au Unix, mais naturellement avec beaucoup moins de "features" - mais il est aussi beaucoup plus simple :^)

 proc cal {{month {}} {year {}}} {
    if {$month eq ""} {set month [clock format [clock sec] -format %B]}
    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
 }

#-- Essayons-le...

 puts [cal [lindex $argv 0] [lindex $argv 1]]

Kroc - 27/03/2007 : Ta procédure numberofdays est très astucieuse Richard !


GM - 7/08/2009 : Quelques aménagements pour mettre le calendier dans une fenêtre, des boutons pour changer le mois, et la mise en évidence du jour actuel.

 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
 }
 proc affiche { jour nbmois year } {
    .txt delete 2.0 end
    .txt insert end \n

    set yeekday [clock format [clock scan "$nbmois/1/$year"] -format %w]
    .txt insert end [string repeat "\t" $yeekday]

    set maxd [numberofdays $nbmois $year]
    for {set d 1} {$d <= $maxd} {incr d} {
      .txt insert end \t
      if { $jour==$d } { set tag actuel} else { set tag ""}
      .txt insert end [format %2d $d] $tag
      if {[incr yeekday]>6} { .txt insert end \n; set yeekday 0}
      }
 }
 proc change { sens  } {
    global jour decm year lesmois

    incr decm $sens;
    if { $decm<=0 } { set decm 12; incr year -1}
    if { $decm>12 } { set decm 1; incr year }
    affiche $jour $decm $year
    .f.t configure -text  "[lindex $lesmois $decm] $year"
    }
 #--------------------------------------------
 set month [clock format [clock sec] -format %B]
 set year [clock format [clock sec] -format %Y]
 set jour [clock format [clock sec] -format %e]

 set lesmois { 0 Janvier Fevrier Mars Avril Mai Juin Juillet Aout Septembre Octobre Novembre Décembre }
 scan [clock format [clock scan "1 $month $year"] -format %m] %d decm

 frame .f
 pack .f
 button .f.bp -bd 1 -pady 0 -padx 2 -text "<<" -command "change -1"
 pack .f.bp -side left
 label .f.t -pady 2 -padx 5 -text "[lindex $lesmois $decm] $year"
 pack .f.t  -side left
 button .f.bs -bd 1 -pady 0 -padx 2 -text ">>" -command "change +1"
 pack .f.bs -side left

 text .txt -height 8 -padx 0 -pady 5 -width 32 -bd 0 -bg #eeeeee -font {Helvetica 10 } -tabs {0.9c right}
 pack .txt
 .txt tag configure actuel -background yellow
 .txt insert end "\tDim\tLun\tMar\tMer\tJeu\tVen\tSam\n"
 affiche $jour $decm $year

Il y a un peu plus de lignes de code, mais cela reste encore un petit calendrier.