E R
E R

Reputation: 490

Get number of days between two Dates excluding weekends

I subtract two dates using below code

Dim OpenDate, ClosedDate As DateTime
dim Result as String
OpenDate = Convert.ToDateTime(some string contain date and time)
ClosedDate = Convert.ToDateTime(some string contain date and time)
Result = ClosedDate.Subtract(OpenDate).ToString

it works fine with correct result in format (day.hour:minute:second )

what i need is

if period between closed and opened date contain Friday or Saturday subtract from result

Ex. if result 9.03:02:10 contain 2 Saturday and Friday it must be 6.03:02:10 and so on

Upvotes: 0

Views: 4922

Answers (2)

Kevin Deenoo
Kevin Deenoo

Reputation: 21

It should really be:

Select day = startDay.AddDays(d)

As the startday of the range specified may not always be today.

Upvotes: 2

Tim Schmelter
Tim Schmelter

Reputation: 460048

A naive but readable approach:

Public Shared Function GetBusinessDays(startDay As DateTime, endDay As DateTime) As Integer
    Dim today = Date.Today
    Dim weekend = {DayOfWeek.Saturday, DayOfWeek.Sunday}
    Dim businessDays = 
        From d In Enumerable.Range(0, (endDay.Date - startDay.Date).Days + 1)
        Select day = today.AddDays(d)
        Where Not weekend.Contains(day.DayOfWeek)
    Return businessDays.Count()
End Function

Test:

Dim days As Int32 = GetBusinessDays(Date.Now, Date.Now.AddDays(9))
Console.Write(days) ' 7

The LINQ query first creates a range of integers from 0 to days (+1 because including last day). Then it creates Date objects via today.AddDays(days). Since weekend is an array of DayOfWeek you can use Enumerable.Contains to take only dates which are not weekend-dates. The last step is to execute the query by using Enumerable.Count to get the number of business days.

You could improve it by providing a ParamArray for the banking-holidays:

Public Shared Function GetBusinessDays(startDay As DateTime, endDay As DateTime, ParamArray bankHoliday As Date()) As Integer
    Dim today = Date.Today
    Dim nonWorkingDays = New HashSet(Of Date)(bankHoliday)
    Dim weekend = {DayOfWeek.Saturday, DayOfWeek.Sunday}
    Dim businessDays =
        From d In Enumerable.Range(0, (endDay - startDay).Days + 1)
        Select day = today.AddDays(d)
        Where Not weekend.Contains(day.DayOfWeek) AndAlso Not nonWorkingDays.Contains(day)
    Return businessDays.Count()
End Function

That works as it is even if you don't have bank holiday days. If you have one or multiple you can either pass a real array as argument or single objects like here for christmas:

Dim christmas = New Date(2014, 12, 25)
Dim days As Int32 = GetBusinessDays(Date.Now, Date.Now.AddDays(9), christmas)

or few single objects:

Dim christmasEve = New Date(2014, 12, 24)
Dim days As Int32 = GetBusinessDays(Date.Now, Date.Now.AddDays(9), christmasEve, christmas)

Upvotes: 8

Related Questions