Version 4 of Tk Dual Zone Clock

Updated 2004-11-23 11:32:21

The concept of this page is to become a place for those of us who are not professional programmers. A place where you don't have to be embarrassed about asking a 'dumb' question. (NOTE: The pros on clt have always been gracious and helpful anyway!) Having trouble with a script? Post the problem part here. Want someone else to take a look at something you are working on and suggest comments or improvements? Put it here. A place where we can work together to improve our skills, or perhaps help each other complete a project. (Don't worry about a lack of 'professional' help - many of the regulars won't be able to resist!)


On the other hand, if your question fits better into one of the other pages, please use that location. The idea of segregating the casual programmers , to me (as a casual Tcl programmer), is degrading and insulting... And if questions end up here randomly instead of more appropriate spots, we end up with a hodge podge effect.


We seem to have different definitions of 'casual programmer'. My use of the term was to describe those of us who are not professional programmers, for which, I believe tcl/tk is the perfect language. (I also believe tcl/tk is ideal for beginners)

Mustering up the courage to make a first post to clt several years ago was, well (for me at least) difficult, so my original thought was that a beginner might feel more comfortable here.

I would never intentionally post any comment to any newsgroup, or on the Wiki that could be construed as degrading or insulting. If you feel insulted or somehow degraded, my sincerest apology.

This page was originally posted to the wiki prior to the rise in the activity here, and the corresponding rise of posts on clt.

I do wholeheartedly agree with your point on posting questions in a more appropriate spot -it seemed to me a good idea at the time, but now seems outdated. I encourage all beginners, newbies, amatuers and others to read clt for awhile, do a google search of the newsgroup archive to look for an answer to their question, and then post to clt. As I have stated before, clt is the best, friendliest and most helpful group anywhere on the net!

so 6/22/01


So let me start this off with a little something I have been working on:


 #!/usr/bin/wish

 label .local_time -textvariable timezone_name
 set timezone_name [clock format [clock scan now] -format "%Z"]

 label .gmt_time -textvariable tz_name
 if {$tcl_version >= 8.3} {
        set tz_name [clock format [clock scan now] -gmt 1\
        -format "%Z"]
        } else {
        set tz_name "GMT"
 }

 grid .local_time -row 0 -columnspan 1
 grid .gmt_time -row 0 -column 1 -columnspan 1

 entry .local_date_entry
 entry .gmt_date_entry
 grid .local_date_entry -row 1 -column 0 -columnspan 1
 grid .gmt_date_entry -row 1 -column 1 -columnspan 1

 entry .local_time_entry -textvariable local_time
 entry .gmt_time_entry -textvariable gmt_time

 grid .local_time_entry -row 2 -column 0 -columnspan 1
 grid .gmt_time_entry -row 2 -column 1 -columnspan 1

 set local_date [clock format [clock scan now]\
 -format "%A %B %d, %Y"]

 set gmt_date [clock format [clock scan now] -gmt 1\
 -format "%A %B %d, %Y"]

 .local_date_entry insert 0 $local_date
 .gmt_date_entry insert 0 $gmt_date

 set local_length [string length $local_date]
 set gmt_length [string length $gmt_date]

 .local_date_entry configure -width $local_length -justify center
 .gmt_date_entry configure -width $gmt_length -justify center

 .local_time_entry configure -width $local_length -justify center
 .gmt_time_entry configure -width $gmt_length -justify center

 proc local_clock:set var {
   global $var
   set $var [clock format [clock seconds] -format "%I:%M:%S %p" ]
   after 200 [list local_clock:set $var]
 }
 local_clock:set local_time

 proc gmt_clock:set var {
   global $var
   set $var [clock format [clock scan now] -gmt 1\
   -format "%I:%M:%S %p" ]
   after 200 [list gmt_clock:set $var]
 }
 gmt_clock:set gmt_time

 tk appname "Double Clock"

Anyone who wants to use this in any manner whatsoever, is welcome to it. Most of the code for the clocks was found doing a search on clt. (I just changed the format a little)

It is easily possible to use other time zones, but I wish I could figure out a way to do this using time zone mnemonics and/or military time zones. Any suggestions? so

DKF - 20000612: Up to (and including) 8.3 at least, you'd need to perform the timezone adjustment yourself. However, you can use [clock scan] (on most platforms at least) to help you get the offset:

  proc getClockOffset {timezone} {
      # Do it this way to avoid UNIXism assumption...
      set epoch [clock format 0 -format "%b %d %Z %H:%M:%S %Y" -gmt 1]
      regsub GMT $epoch $timezone datestring
      return [expr {-[clock scan $datestring]}]
  }

This should help you convert timezones (including the military designations, IIRC) into offsets so you can format the date correctly. The only awkward bit is getting a list of timezones that the code supports, and I'm afraid that you might need to delve into the source code for that (there are some interesting clashes in there!)

(Note that I specify the format because on some platforms the usual output of [clock format] can't be understood by [clock scan], and the format is needed to avoid hard-coding in the assumption that the epoch begins with 1970, as this might not hold on all platforms...)

Your task, should you choose to accept it, is to combine this code into the preceding code to create a more internationally-aware application...


Donal - thanks for the input. I am working on this from time to time. Never figured on the problems with the time-zone mnemonics! so


See also Date and Time Issues, where the above kind of questions are dealt with.


On another subject - A recent posting on clt reminded me of my first foray into the newsgroup. When I first began tinkering with tcl/tk, I could find examples of scripts to design a data input form, but nothing on how to *save* the data. I have always meant to post something somewhere for beginners (like me), but never got around to it - til now, a *simplistic*, *minimalist*, dataform, that works:


 frame .entryframe
 label .entryframe.l1 -text "Last Name"
 entry .entryframe.e1 -textvariable data_array(lastName)
 label .entryframe.l2 -text "First Name"
 entry .entryframe.e2 -textvariable data_array(firstName)

 grid .entryframe.l1 .entryframe.e1
 grid .entryframe.l2 .entryframe.e2
 grid .entryframe

 frame .controlframe
 button .controlframe.clear -text "Clear" -command {  clear_card }
 button .controlframe.find -text "Find" -command { file_get }
 button .controlframe.save -text "Save" -command { file_save }
 button .controlframe.exit -text "Exit" -command { exit }

 grid .controlframe.clear .controlframe.find .controlframe.save .controlframe.exit
 grid .controlframe

 proc file_save { } {
        global data_array

        ## DKF: A more efficient way to dump an array to a file is below
        #foreach index [array names data_array] {
        #append data "set data_array($index) {$data_array($index)}" \n
        #}

        set file_types {
                {"All Files" * }
        }
        set filename [tk_getSaveFile -filetypes $file_types\
        -defaultextension .mdf -initialfile         $data_array(lastName)$data_array(firstName)\
        ]
        # ASHISH: A small check. If Cancel is pressed, then you get a stack trace
        if {$filename != "" } {
             set fileid [open $filename w]
             # puts $fileid $data
             puts $fileid [list array set data_array [array get data_array]]
             close $fileid
        }
 }

 proc file_get {  } {
        global data_array
        clear_card
        set file_types {
                {"My Data File" { .mdf }}
        }
        set filename [tk_getOpenFile -filetypes $file_types\
        -defaultextension . -initialdir [pwd]]
        # ASHISH: A small check. If Cancel is pressed, then you get a stack trace
        if {$filename != "" } {
             source $filename
        }
 }

 proc clear_card { } {
        .entryframe.e1 delete 0 end
        .entryframe.e2 delete 0 end

 }

All you pros please feel free to comment on better ways to do this, script improvements, etc.

DKF - As you can see above, it is easier to use [array get] and [array set] to dump and reload arrays from files, though the general principle of loading data via source is a good one for non-binary data.