chaitanyak
chaitanyak

Reputation: 25

How to calculate the time span in Tcl using clock commands

I need to calculate the time difference between two periods of a day in a 24:00 hr format clock using Tcl.

Let's say my start time is 06:30:00 in the morning and end time is 18:30:00 in the evening. I've tried the following in using Active Tcl 8.5 and 8.6 in windows.

set morn [clock scan 06:30:00 -format %H:%M:%S]
set even [clock scan 18:30:00 -format %H:%M:%S]
set diff [clock format [expr $even - $morn ] -format %H:%M:%S]

The answer is supposed to be 12:00:00 which is the actual difference but, I get the answer as 17:30:00 which is totally confusing.

I presume that the GMT time difference of 05:30:00 is being added to the difference as I'm in a GMT+5:30 time zone (IST).

How do I get the exact difference?

Upvotes: 2

Views: 5634

Answers (2)

Choca Croc
Choca Croc

Reputation: 11

I don't understand why you don't use the -timezone option ? I'm in TZ=CET so for me the answer is 13:00:00

If I add the "-timezone UTC" option I get the right answer:

set morn [clock scan 06:30:00 -format %T]
puts "morn = $morn"

set even [clock scan 18:30:00 -format %T]
puts "even = $even"

set diff [clock format [expr $even - $morn ] -format "%Y:%m:%d %T"]
puts "diff = $diff"

puts "difference = [expr $even - $morn]"

puts "with -timezone UTC = [clock format [expr $even - $morn ] -timezone UTC -format %T]"

The display is

morn = 1496723400
even = 1496766600
diff = 1970:01:01 13:00:00
difference = 43200
with -timezone UTC = 12:00:00

Upvotes: 0

Donal Fellows
Donal Fellows

Reputation: 137567

The clock command doesn't have anything in it to convert time intervals into human-readable form, as it focuses on handling time instants.

You're correct that the timezone you're in caused that time interval to come out strange. Passing the -gmt 1 option would have helped a bit, but only until you got a time interval of 24 hours or more. At that point, it would have looped round and looked very strange.

The way to deal with this is to do the formatting directly. This isn't very hard.

proc formatTimeInterval {intervalSeconds} {
    # *Assume* that the interval is positive
    set s [expr {$intervalSeconds % 60}]
    set i [expr {$intervalSeconds / 60}]
    set m [expr {$i % 60}]
    set i [expr {$i / 60}]
    set h [expr {$i % 24}]
    set d [expr {$i / 24}]
    return [format "%+d:%02d:%02d:%02d" $d $h $m $s]
}
puts [formatTimeInterval [expr {$even - $morn}]]
#==> +0:12:00:00

Upvotes: 2

Related Questions