1 # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4
3 class tlc
::Businessdays {
9 variable workday_start
"08:00am"
10 variable workday_end
"05:00pm"
12 variable is_holiday
{} ;# called with epoch secs of day, return 1 if holiday
14 method offset
{interval
{from
"now"}}
18 variable workday_start_offset
19 variable workday_end_offset
24 configbody tlc
::Businessdays::workday_start { #<<<
25 set workday_start_offset
[expr {[clock scan $workday_start] - [clock scan "00:00am"}]
29 configbody tlc
::Businessdays::workday_end { #<<<
30 set workday_end_offset
[expr {[clock scan $workday_end] - [clock scan "00:00am"}]
34 body tlc
::Businessdays::constructor {args
} { #<<<
39 body tlc
::Businessdays::offset {interval
{from
"now"}} { #<<<
41 set from
[clock seconds
]
43 if {![string is digit
-strict $from]} {
44 set from
[clock scan $from]
48 set month
[clock format $from -format "%b %Y"]
49 set daystart
[clock scan "1 $month"]
50 set workday_start_offset
[expr {[clock scan "1 $month $workday_start"] - $daystart}]
51 set workday_end_offset
[expr {[clock scan "1 $month $workday_end"] - $daystart}]
53 set initial
[clock add
$from {*}$interval]
54 set remaining
[expr {$initial - $from}]
56 error "Negative intervals not allowed"
60 set daystart
[clock scan [clock format $pointer -format "%Y-%m-%d"] -format "%Y-%m-%d"]
62 while {$daystart <= $pointer - 86400} {
65 if {$is_holiday ne
""} {
66 if {[uplevel #0 $is_holiday [list $daystart]]} {
71 set dow
[clock format $pointer -format "%a"]
81 [expr {$daystart + $workday_start_offset - 1}] \
84 [expr {$daystart + $workday_end_offset + 1}] \
85 [expr {$daystart + 86400 - 1}] \
93 [expr {$daystart + 86400 - 1}] \
99 lassign
$gap gap_start gap_end
100 if {$pointer >= $gap_start && $pointer <= $gap_end} {
101 set pointer
[expr {$gap_end + 1}]
105 set last_gap_end
[lindex $gaps end
1]
106 if {$pointer == $last_gap_end + 1} continue
108 if {$remaining <= 0} break
110 if {[info exists last_end
]} {
114 lassign
$gap gap_start gap_end
115 if {[info exists last_end
] && $gap_start > $pointer} {
116 set chunk
[expr {$gap_start - $pointer - 1}]
117 if {$remaining >= $chunk} {
118 set pointer
$gap_start
119 set remaining
[expr {$remaining - $chunk}]
121 set pointer
[expr {$pointer + $remaining}]
126 set last_end
$gap_end