Version 6 of Splitting an amount in parts

Updated 2007-08-18 13:19:34 by MJ

MJ - A frequent question on the Tcl Chat is how to split the number of seconds in the number of days, minutes etc. The following proc provides this and allows you to specifiy the divisors of the different units, making it very flexible. A divider of {} (or a divider that is not specified) means that this unit should not be split any further (see examples below)

For example the following {a x b y c z d} would translate to: A d is z c's which are y b's consisting of x a's.

Note that this inly works for integer amounts and dividers.

 proc split_amount {amount dividers} {
   set result {}
   foreach {unit divider} $dividers {
       if {$amount == 0} break;
       if {$divider eq {}} {
           set result "$amount$unit $result"
           break
       } 
       set result "[expr {$amount % $divider}]$unit $result"
       set amount [expr {$amount/$divider}]
   }
   return $result
 }

Example usage:

 % split_amount [clock seconds] {s 60 m 60 h 24 d 365 y {}}
 37y 238d 13h 2m 59s
 % # or
 % split_amount [clock seconds] {s 60 m 60 h 24 d 365 y}
 37y 238d 13h 2m 59s    
 % split_amount [clock seconds] {{ seconds} 60 { minutes and} 60 { hours,} 24 { days,} 365 { years,} {}}
 37 years, 238 days, 13 hours, 4 minutes and 7 seconds
 % split_amount 2234141 {{ gram} 1000 { kilogram and} 1000 { tonne,}}
 2 tonne, 234 kilogram and 141 gram