proc add_days {start days} {
set 1day [expr {3600 * 24}]
set end [expr {$start + [days2seconds $days]}]
set diff [expr {$end - $start}]
set weeks [expr {$diff / ($1day * 7)}]
set remainder [expr {($diff - $weeks * $1day * 7) / $1day}]
set startdow [clock format $start -format "%u"]
set enddow [clock format $end -format "%u"]
set add 0
incr add [expr {$weeks * 2}]
incr add [expr {$startdow > $enddow ? 2 : 0}]
incr add [expr {$startdow == 6 ? 2 : 0}]
incr add [expr {$startdow == 7 ? 1 : 0}]
set realend [expr {$end + $add * $1day}]
set realenddow [clock format $realend -format "%u"]
set add [expr {$realenddow == 6 ? 2 : 0}]
incr add [expr {$realenddow == 7 ? 2 : 0}]
puts "ordered on [clock format $start] and should take $days days"
puts "arrival on [clock format [expr {$realend + $add * $1day}]]"
}Please feel free to hack at the code in-line rather than tacking on new versions, unless they are radically different approaches - like the simple one of simply starting on the start day and going through each day and either counting it or not depending on whether it is a weekend day.TODO: holidays, perhaps adjust it to make weekend days configurable (depending on the country, weekend days might vary).If the Italian postal system gets its hands on the package, double the time, approximately;-)
davidw - The naive way of doing this is actually pretty simple... maybe enough that it's worth doing it this way even though it's kind of annoying to bludgeon one's way through:
proc is_holiday? {date} {
array set holidays {
"01 01" X
"06 01" X
"25 04" X
"01 05" X
"02 06" X
"15 08" X
"01 11" X
"08 12" X
"25 12" X
"26 12" X
}
set dm [clock format $date -format "%d %m"]
if { [info exists holidays($dm)] } {
puts "Holiday [clock format $date]"
return 1
} else {
return 0
}
}
proc is_weekend? {date} {
set dow [day_of_week $date]
if { $dow == 6 || $dow == 7 } {
puts "Weekend [clock format $date]"
return 1
} else {
return 0
}
}
proc add_days {start days} {
set current $start
puts "Started on [clock format $start]"
set 1day [expr {3600 * 24}]
set i 0
while {$i < $days} {
incr current $1day
if { [is_weekend? $current] || [is_holiday? $current] } {
continue
}
incr i
}
puts "Delivered on [clock format $current]"
}See also: Calculating the Date of Easter

