Вы на правильном пути, вам просто нужно проверить национальные праздники, а также (если это не выходные) и вычесть выходные и национальные праздники из фактического количества дней, чтобы получить количество рабочих дней. Попробуйте это:
' You need to keep a record of national holidays and keep it updated. Probably best to do this
' outside of your function. You can't use a constant to store an array, you could just dim a
' regular variable, but IMO a better alternative would be to use "Application" and set it in
' your global.asa file under "Sub Application_OnStart"... or just use a database.
Application("NationalHolidays") = array("01-01-2019","19-04-2019","20-04-2019","01-05-2019","21-05-2019","29-06-2019","16-07-2019","15-08-2019","18-09-2019","19-09-2019","20-09-2019","12-10-2019","31-10-2019","01-11-2019","08-12-2019","25-12-2019")
function calcDays(fromDate,toDate)
Dim ActualDays, Weekends, NationalHolidays, WorkingDays, nhIndex, x, y
fromDate = cDate(fromDate)
toDate = cDate(toDate)
ActualDays = DateDiff("d",fromDate,toDate)
Weekends = 0
NationalHolidays = 0
WorkingDays = 0
nhIndex = 0
' Loop from start day to end day
for x = 0 to ActualDays + 1
' Count the weekends
if WeekDay(DateAdd("d",x,fromDate)) = 1 OR WeekDay(DateAdd("d",x,fromDate)) = 7 then
Weekends = Weekends + 1
else
' Check for national holidays if it's not a weekend
if NOT nhIndex > uBound(Application("NationalHolidays")) then
for y = nhIndex to uBound(Application("NationalHolidays"))
' This if/else logic assumes Application("NationalHolidays") is in ascending order.
if DateAdd("d",x,fromDate) = cDate(Application("NationalHolidays")(y)) then
NationalHolidays = NationalHolidays + 1
' Keep track of the last national holiday found and start from that
' position + 1 on the next check.
nhIndex = y + 1
exit for
elseif cDate(Application("NationalHolidays")(y)) < DateAdd("d",x,fromDate) then
' Keep count of national holidays that have already passed and skip them
' on the next check.
nhIndex = y + 1
elseif cDate(Application("NationalHolidays")(y)) > DateAdd("d",x,fromDate) then
' The national holiday dates have exceeded the current date, there's no
' point in continuing checking.
exit for
end if
next
end if
end if
next
' Working days is the number of days between "fromDate" and "toDate" minus weekends and national holidays
WorkingDays = (ActualDays-Weekends-NationalHolidays)
calcDays = "<p>Actual Days: " & ActualDays & "</p>" &_
"<p>National Holidays: " & NationalHolidays & "</p>" &_
"<p>Weekends: " & Weekends & "</p>" &_
"<p>Working Days: " & WorkingDays & "</p>"
end function
response.write calcDays("29-04-2019","13-05-2019")
29 апреля 2019 до 13 мая 2019
Выход:
Фактические дни: 14
Национальные праздники: 1
Выходные: 4
Рабочие дни: 9
РЕДАКТИРОВАТЬ: Для расчета Date X
+ Y Working Days
= Date Z
(как задано в вашем вопросе), вы можете использовать эту функцию:
function AddWorkingDays(startDate,workingDays)
startDate = cDate(startDate)
Dim DayCount, workingDayCount, nhIndex, isNationalHoliday, x
DayCount = 0
workingDayCount = 0
nhIndex = 0
do until workingDayCount = workingDays
' Make sure it's not a weekend
if NOT(WeekDay(DateAdd("d",DayCount,startDate)) = 1 OR WeekDay(DateAdd("d",DayCount,startDate)) = 7) then
isNationalHoliday = false ' default
' Make sure it's not a national holiday
if NOT nhIndex > uBound(Application("NationalHolidays")) then
for x = nhIndex to uBound(Application("NationalHolidays"))
' This if/else logic assumes Application("NationalHolidays") is in ascending order.
if DateAdd("d",DayCount,startDate) = cDate(Application("NationalHolidays")(x)) then
isNationalHoliday = true
' Keep track of the last national holiday found and start from that
' position + 1 on the next check.
nhIndex = x + 1
exit for
elseif cDate(Application("NationalHolidays")(x)) < DateAdd("d",DayCount,startDate) then
' Keep count of national holidays that have already passed and skip them
' on the next check.
nhIndex = x + 1
elseif cDate(Application("NationalHolidays")(x)) > DateAdd("d",DayCount,startDate) then
' The national holiday dates have exceeded the current date, there's no
' point in continuing checking.
exit for
end if
next
end if
if NOT isNationalHoliday then workingDayCount = workingDayCount + 1 ' It's a working day!
end if
' Keep count of the total number of days needed to make up the working day target
DayCount = DayCount + 1
loop
AddWorkingDays = DateAdd("d",DayCount,startDate)
end function
' As in your question, calculate 15 working days from April 25th 2019
response.write AddWorkingDays("25-04-2019",15)
25 апреля 2019 + 15 рабочих дней
Выход:
17 мая 2019