The code below will convert human-readable strings to a duration in seconds. It breaks up the input string in words and analyse the result to be able to understand constructs such as "2 weeks" or "1y" (for one year, note the missing space). More examples are provided at the end.
proc howlong {len unit} {
if { [string is integer -strict $len] } {
switch -glob -- $unit {
"\[Yy\]*" {
return [expr {$len*31536000}]; # Leap years?
}
"\[Mm\]\[Oo\]*" -
"m*" {
return [expr {$len*2592000}]
}
"\[Ww\]*" {
return [expr {$len*604800}]
}
"\[Dd\]*" {
return [expr {$len*86400}]
}
"\[Hh\]*" {
return [expr {$len*3600}]
}
"\[Mm\]\[Ii\]*" -
"M" {
return [expr {$len*60}]
}
"\[Ss\]*" {
return $len
}
}
}
return 0
}
proc duration { str } {
set words {}
while {[scan $str %s%n word length] == 2} {
lappend words $word
set str [string range $str $length end]
}
set seconds 0
for {set i 0} {$i<[llength $words]} {incr i} {
set f [lindex $words $i]
if { [scan $f %d%n n length] == 2 } {
set unit [string range $f $length end]
if { $unit eq "" } {
incr seconds [howlong $n [lindex $words [incr i]]]
} else {
incr seconds [howlong $n $unit]
}
}
}
return $seconds
}
puts stdout [duration 1w]
puts stdout [duration " 2 months 4d"]
puts stdout [duration " 2y -3 m"]
Discussion
For another look at something similar (human ways of expressing date and time), including time expressions like this, "2 wk -5min after Monday after 6:00 am 400sec" the
Multics date_time command
http://www.multicians.org/mtbs/mtb617-03.html handled many different kinds of human-readable cases.