我已经创建了一个函数来获取 2 个日期(含)之间的工作日列表,减去假期和周末,如下所示:
Function GetWorkingDates(startDate As Date, endDate As Date, holidayDates As Date()) As List(Of Date)
If endDate < startDate Then
Throw New ArgumentOutOfRangeException("endDate", "Value must be equal or larger than 'startDate' parameter.")
End If
Dim listDate As List(Of Date) = Enumerable.Range(0, 1 + CInt((endDate - startDate).TotalDays)).Select(Function(n) startDate.AddDays(n)).ToList
' if defined, remove holidays from listDate
If holidayDates IsNot Nothing Then listDate.RemoveAll(Function(d) holidayDates.Contains(d))
' remove weekends as defined below
Dim weekends As DayOfWeek() = {DayOfWeek.Saturday, DayOfWeek.Sunday}
listDate.RemoveAll(Function(d) weekends.Contains(d.DayOfWeek))
Return listDate
End Function
为了获得总小时数,我刚刚创建了一个新函数来从上面现有函数的结果中获取总时间跨度:
Function GetTotalWorkingTimeSpan(startDateTime As Date, endDateTime As Date, startWorkTime As TimeSpan, endWorkTime As TimeSpan, holidayDates As Date()) As TimeSpan
If endDateTime < startDateTime Then
Throw New ArgumentOutOfRangeException("endDate", "Value must be equal or larger than 'startDate' parameter.")
End If
If endWorkTime < startWorkTime Then
Throw New ArgumentOutOfRangeException("endWorkTime", "Value must be equal or larger than 'startWorkTime' parameter.")
End If
' get list of working days minus weekends and holidays
Dim lstWorkDays As List(Of Date) = GetWorkingDates(startDateTime.Date, endDateTime.Date, holidayDates)
' get total minutes by bultiplying total working days and total minutes per day
Dim totalMinutes As Double = lstWorkDays.Count * (endWorkTime - startWorkTime).TotalMinutes
' deduct the first day's hour if occured later than the startWorkTime, only if startDateTime is a working day
If lstWorkDays.Contains(startDateTime.Date) Then
Dim minutesOffset As Double = (startDateTime.TimeOfDay - startWorkTime).TotalMinutes
If minutesOffset > 0 Then totalMinutes -= minutesOffset
End If
' deduct the last day's hour if occured ealier than the endWorkTime, only if endDateTime is a working day
If lstWorkDays.Contains(endDateTime.Date) Then
Dim minutesOffset As Double = (endWorkTime - endDateTime.TimeOfDay).TotalMinutes
If minutesOffset > 0 Then totalMinutes -= minutesOffset
End If
Return TimeSpan.FromMinutes(totalMinutes)
End Function
使用您的数据,我创建了一个测试控制台:
Sub Main()
Dim sdt As Date = #5/27/2013 6:00:00 AM#
Dim edt As Date = #5/28/2013 10:30:00 AM#
Dim hols() As Date = {} ' add holiday dates here
Dim lst As List(Of Date) = GetWorkingDates(sdt, edt, Nothing) ' or simply Nothing to not check for holidays
Console.WriteLine("Num of working days = " & lst.Count)
Console.WriteLine()
Console.WriteLine("List of working dates:")
lst.ForEach(Sub(d) Console.WriteLine("* " & d.ToLongDateString))
Console.WriteLine()
Dim totalWorkingTimeSpan As TimeSpan = GetTotalWorkingTimeSpan(sdt, edt, New TimeSpan(9, 0, 0), New TimeSpan(17, 0, 0), hols)
Console.WriteLine("Total working hours = " & totalWorkingTimeSpan.TotalMinutes & " minutes, or " & totalWorkingTimeSpan.TotalHours & " hours")
PromptExit()
End Sub
控制台应用程序的输出: