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