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.