Hello.
Calculate the number of workdays between two dates.
It does what it says, it calculates any workdays between a startDate and an endDate. The current day is included if it is a workday. The end day is not included. It handles time of day in a peculiar way: If the time of the start day is greater than the time of the end day, then the start day is subtracted, unless the end date is during a weekend.
The idea is that when you track something during a week, then it is about workdays, so if you have an event scheduled during a working day, then you count down whole working days to that event. If the event falls within a weekend, then the hours of a working day isn’t considered, so say a friday before something happening on a saturday is considered to be a full day.
If you have other days you want to subtract from workingdays, after you have checked that they are within the timespan, and that the days didn’t fall on a saturday or sunday this year, then you subtract those from the number of days returned from this handler.
You should check that the difference between the end date and start date is not lesser than 0 days.
on workDays(startDate, endDate)
-- http://macscripter.net/viewtopic.php?pid=180688#p180688
-- Copyright © 2015 McUsr, all rights reserved, you may not publish this standalone anywhere else, or take credit for it.
-- You may use it as you see fit, if its functionality is needed for something else.
-- Returns the number of working days in a date interval.
-- working days are the days mondays thru friday.
-- There are two regimes here:
-- 1. The end date is on a working date. We consider the hours.
-- 2. The end date is during a weekend. -We ignore any hours.
copy {startDate, endDate} to {startProbe, endProbe}
set startProbe's time to 0
set endProbe's time to 0
set daydiff to (endProbe - startProbe) div days
set wkdStart to startProbe's weekday as integer
set wkdEnd to endProbe's weekday as integer
if daydiff > 0 then
if daydiff < 7 then
if wkdStart > wkdEnd then
if wkdStart < 7 and wkdEnd > 1 then
set workingdays to daydiff - 2
else
set workingdays to daydiff - 1
end if
else
set workingdays to daydiff -- the current day counts as a workingday
if wkdEnd = 7 and wkdStart = 1 then set workingdays to workingdays - 1 -- wkdEnd can't be 1
end if
if wkdEnd is not in {1, 7} and wkdStart is not in {1, 7} and startDate's time > endDate's time then ¬
set workingdays to workingdays - 1
return workingdays
else if daydiff mod 7 = 0 then
-- Thanks to Nigel Garvey for spotting the bug.
set workingdays to daydiff - 2 * daydiff div 7
if wkdStart is not in {1, 7} and startDate's time > endDate's time then set workingdays to workingdays - 1
return workingdays
else
if wkdStart > 1 then
set wkStartWkDays to (7 - wkdStart)
if wkStartWkDays > 0 then
set daydiff to daydiff - wkStartWkDays
else
set daydiff to daydiff - 2
end if
else
set daydiff to daydiff - 1
set wkStartWkDays to 0
end if
if wkdEnd < 7 and wkdEnd > 1 then
set wkEndWkDays to wkdEnd - 2 -- The end day doesn't count
set daydiff to daydiff - wkdEnd
else
set daydiff to daydiff - 2
set wkEndWkDays to 0
end if
set daydiff to daydiff - ((daydiff div 7) * 2)
set workingdays to wkStartWkDays + daydiff + wkEndWkDays
end if
if (wkdStart is not in {1, 7} and wkdEnd is not in {1, 7}) and startDate's time > endDate's time then
set workingdays to workingdays - 1
else if wkdStart is in {1, 7} and wkdEnd is in {1, 7} and startDate's time > endDate's time then
set workingdays to workingdays + 1
end if
return workingdays
else
return 0
end if
end workDays
Edit
14:00 CEST: I have simplified the handler, just a little bit, without changing any functionality.
2015/05/15 04.55 CEST: Removed some unnecessary code, given the way it works now.