Как я могу рассчитать, сколько рабочих дней до определенной даты? - PullRequest
1 голос
/ 29 апреля 2019

Мне нужно сделать что-то вроде счетчика рабочих дней, но я не знаю, как:

Допустим, сегодня кто-то делает запрос 04-25-2019, и его нужно утвердить в течение 15 рабочих дней., это было бы около 05-16-2019, как это можно сделать?Я понятия не имею, и я должен включить праздники моей страны.

Что будет:

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

Я пробовал это:

<%
DateFrom = "10/1/2012"
DateTo = "10/31/2012"
Weekends = 0
ActualDays = 0

' Step 1: Get the actual days
ActualDays = DateDiff("d", DateFrom, DateTo)

' Step 2: Find the weekends
For x = 0 To ActualDays - 1
    xDate = DateAdd("d", x, DateFrom)
    If Weekday(xDate, 1) = 1 Or Weekday(xDate, 1) = 7 Then
        Weekends = Weekends + 1
    End If
Next

WorkingDays = ActualDays - Weekends

response.Write "ActualDays: "&ActualDays  &" Weekends: "& Weekends &" WorkingDays: "& WorkingDays
%>

но этоне получилось, как я хотел.

1 Ответ

1 голос
/ 29 апреля 2019

Вы на правильном пути, вам просто нужно проверить национальные праздники, а также (если это не выходные) и вычесть выходные и национальные праздники из фактического количества дней, чтобы получить количество рабочих дней. Попробуйте это:

' 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

...