Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calculate date add, but only weekdays

Tags:

date

vb.net

I would like to calculate a new date simply by using the build-in dateadd function, but take into account that only weekdays should be counted (or 'business days' so to speak).

I have come up with this simple algorithm, which does not bother about holidays and such. I have tested this with some simple dates, but would like some input if this can be done in better ways.

This sample assumes a week with 5 business days, monday-friday, where first day of the week is monday. Dateformatting used here is d-m-yyyy, the sample calculates with a startdate of october 1, 2009.

Here is the simple form:

Dim d_StartDate As DateTime = "1-10-2009"
Dim i_NumberOfDays As Integer = 12
Dim i_CalculateNumberOfDays As Integer 

If i_NumberOfDays > (5 - d_StartDate.DayOfWeek) Then
    i_CalculateNumberOfDays = i_NumberOfDays
Else
    i_CalculateNumberOfDays = i_NumberOfDays + (Int(((i_NumberOfDays + (7 - d_StartDate.DayOfWeek)) / 5)) * 2)
End If

MsgBox(DateAdd(DateInterval.Day, i_CalculateNumberOfDays, d_StartDate))

Which I try to explain with the following piece of code:

''' create variables to begin with
Dim d_StartDate as Date = "1-10-2009"
Dim i_NumberOfDays as Integer = 5

''' create var to store number of days to calculate with
Dim i_AddNumberOfDays as Integer 


''' check if amount of businessdays to add exceeds the 
''' amount of businessdays left in the week of the startdate
If i_NumberOfDays > (5 - d_StartDate.DayOfWeek) Then


    ''' start by substracting days in week with the current day,
    ''' to calculate the remainder of days left in the current week
    i_AddNumberOfDays = 7 - d_StartDate.DayOfWeek

    ''' add the remainder of days in this week to the total
    ''' number of days we have to add to the date
    i_AddNumberOfDays += i_NumberOfDays

    ''' divide by 5, because we need to know how many 
    ''' business weeks we are dealing with
    i_AddNumberOfDays = i_AddNumberOfDays / 5

    ''' multiply the integer of current business weeks by 2
    ''' those are the amount of days in the weekends we have 
    ''' to add to the total
    i_AddNumberOfDays = Int(i_AddNumberOfDays) * 2

    ''' add the number of days to the weekend days
    i_AddNumberOfDays += i_NumberOfDays

Else

    ''' there are enough businessdays left in this week
    ''' to add the given amount of days
    i_AddNumberOfDays = i_NumberOfDays

End If

''' this is the numberof dates to calculate with in DateAdd
dim d_CalculatedDate as Date
d_CalculatedDate = DateAdd(DateInterval.Day, i_AddNumberOfDays, d_StartDate)

Thanks in advance for your comments and input on this.

like image 734
Jorrit Reedijk Avatar asked Jan 20 '26 12:01

Jorrit Reedijk


2 Answers

I used the .DayOfWeek function to check if it was a weekend. This does not include holiday implementation. It has been tested. I realize this question is old but the accepted answer didn't work. However, I did like how clean it was so I thought I'd update it and post. I did change the logic in the while loop.

Function AddBusinessDays(startDate As Date, numberOfDays As Integer) As Date
    Dim newDate As Date = startDate
    While numberOfDays > 0
        newDate = newDate.AddDays(1)

        If newDate.DayOfWeek() > 0 AndAlso newDate.DayOfWeek() < 6 Then '1-5 is Mon-Fri
            numberOfDays -= 1
        End If

    End While
    Return newDate
End Function
like image 147
Tony L. Avatar answered Jan 23 '26 04:01

Tony L.


Public Shared Function AddBusinessDays(ByVal startDate As DateTime, _
                                       ByVal businessDays As Integer) As DateTime
    Dim di As Integer
    Dim calendarDays As Integer

    '''di: shift to Friday. If it's Sat or Sun don't shift'
    di = (businessDays - Math.Max(0, (5 - startDate.DayOfWeek)))

    ''' Start = Friday -> add di/5 weeks -> end = Friday'
    ''' -> if the the remaining (<5 days) is > 0: add it + 2 days (Sat+Sun)'
    ''' -> shift back to initial day'
    calendarDays = ((((di / 5) * 7) _
                   + IIf(((di Mod 5) <> 0), (2 + (di Mod 5)), 0)) _
                   + (5 - startDate.DayOfWeek))

    Return startDate.AddDays(CDbl(calendarDays))

End Function
like image 34
manji Avatar answered Jan 23 '26 04:01

manji