Calculate Elapsed Time Between Two Date/Time Values

For my OpenNTF project !!HELP!! I needed a function to calculate the elapsed time between two events. The code should be able to exclude holidays and weekends. In addition it should calculate the time difference only within workhours. Here is the result of a rainy sunday 🙂
There is another class by Sean Burgess, which does the same stuff than mine.

The following sample returns the amount of time in minutes between two given date/time values

Sub Click(Source As Button)
	Dim startdt As String
	Dim enddt As String
	Dim dtc As New DateTimeCalculator ( "1,7","24.12.2007","7:00~17:00")

	startdt = "18.06.2007 16:59"
	enddt = "19.06.2007 07:01"

	Msgbox dtc.GetElapsedTime(startdt,enddt)
End Sub

Copy the following code to a script library. Type

Use "YourLibName"

into the Options section of your button, agent or whereever you like to use the lib. Don’t forget to include Julian Robichaux’s OpenLog for error trapping.

Class DateTimeCalculator

	Private StartDT As NotesDateTime
	Private EndDT As NotesDateTime
	Private dt3 As NotesDateTime
	Private dt4 As NotesDateTime
	Private dt5 As NotesDateTime
	Private WDENDHOUR As String
	Private WDSTARTHOUR As String
	Private nondays As String
	Private holidays As String

	Sub New (strExcludeDays As String,strExcludeDates As String,SERVICEHOURS As String)
		On Error Goto ERRHANDLE

		WDSTARTHOUR = "00:00"
		WDENDHOUR = "23:59"
		nondays = "0"
		holidays = "[01/01/1899]"

		If SERVICEHOURS <> "" Then
			WDSTARTHOUR = Strtoken(SERVICEHOURS,"~",1)
			WDENDHOUR = Strtoken(SERVICEHOURS,"~",2)
		End If
		If strExcludeDays <> "" Then
			nondays = Implode(Split(strExcludeDays,","),":")
		End If
		If strExcludeDates <> "" Then
			holidays = Implode(Split(strExcludeDates,","),"]:[")
			holidays = "[" & holidays & "]"
		End If

EXITPOINT:
		Exit Sub
ERRHANDLE:
		Call LogError()
		Resume EXITPOINT
	End Sub

	Public Function GetNextBusinessDay (dt1 As String) As String
		On Error Goto ERRHANDLE
		Dim newDT As Boolean
		Set Me.StartDT = New NotesDateTime(dt1)
		NewDt = False
		Set dt3 = New NotesDateTime(Me.StartDT.DateOnly & " " & Me.WDSTARTHOUR)
		Set dt4 = New NotesDateTime(Me.StartDT.DateOnly & " " & Me.WDENDHOUR)
		If Me.StartDT.TimeDifference(dt3) < 0 Then ' StartDT < WDSTARTHOUR
			Set Me.StartDT = dt3
		End If

		If dt4.TimeDifference(Me.StartDT) < 0 Then ' StartDT > WDENDHOUR
			Set Me.StartDT = dt3
			Call Me.StartDT.AdjustDay(1)
		End If

		While Me.GetBusinessDays (StartDT.DateOnly,StartDT.DateOnly ) = 0
			Call StartDT.AdjustDay(1)
			NewDT = True
		Wend

		If NewDT Then
			Set dt5 = New NotesDateTime(Me.StartDT.DateOnly & " " & Me.WDSTARTHOUR)
			Set Me.StartDT = dt5
		End If

		GetNextBusinessDay = Me.StartDT.LocalTime

EXITPOINT:
		Exit Function
ERRHANDLE:
		Call LogError()
		Resume EXITPOINT
	End Function

	Private Function GetNumBusinessDayHours () As Integer
		On Error Goto ERRHANDLE
		Dim BDHOURS1 As New NotesDateTime(Today & " " & Me.WDSTARTHOUR)
		Dim BDHOURS2 As New NotesDateTime(Today & " " & Me.WDENDHOUR)
		GetNumBusinessDayHours = Fix(((BDHOURS2.TimeDifference(BDHOURS1)/60)Mod 1440)/60)

EXITPOINT:
		Exit Function
ERRHANDLE:
		Call LogError()
		Resume EXITPOINT
	End Function

	Private Function GetTimeDifference (strStart As String,strEnd As String ) As Long
		On Error Goto ERRHANDLE
		Dim BDSTART As New NotesDateTime(strStart)
		Dim BDEND As New NotesDateTime(strEnd)
		GetTimeDifference = Fix((BDEND.TimeDifference(BDSTART)/60)Mod 1440)

EXITPOINT:
		Exit Function
ERRHANDLE:
		Call LogError()
		Resume EXITPOINT
	End Function

	Public Function GetBusinessDays(dtStart As String,dtEnd As String) As Integer
		On Error Goto ERRHANDLE
		Dim busdays As Variant

		Dim BDS As New NotesDateTime(dtStart)
		Dim BDE As New NotesDateTime(dtEnd)

		busdays = Evaluate(_
		{@BusinessDays([}&_
		Cdat(BDS.DateOnly)& {];[}&_
		Cdat(BDE.DateOnly)& {];}&_
		Me.nondays &{;}&_
		Me.holidays & {)})
		GetBusinessDays = Cint(busdays(0))

EXITPOINT:
		Exit Function
ERRHANDLE:
		Call LogError()
		Resume EXITPOINT
	End Function

	Public Function GetElapsedTime (dtStart As String,dtEnd As String) As Long
		On Error Goto ERRHANDLE
		Dim intStart As Long
		Dim intMiddle As Long
		Dim intEnd As Long
		Dim i As Integer

		Set dt3 = New NotesDateTime(dtStart)
		Set dt4 = New NotesDateTime(dtEnd)
		If dt3.DateOnly = dt4.dateonly Then ' same day
			GetElapsedTime = Me.GetTimeDifference(dtStart,dtEnd)
		Else
			intStart = Me.GetTimeDifference(dtStart,Cstr(dt3.DateOnly & " " & Me.WDENDHOUR))
			intMiddle = 0
			i = Me.GetBusinessDays(dtStart,dtEnd)-2
			If i > 0 Then
				intMiddle = (i*Me.GetNumBusinessDayHours())*60
			End If
			intEnd = Me.GetTimeDifference(Cstr(dt4.DateOnly & " " & Me.WDSTARTHOUR),dtEnd)
			GetElapsedTime = intStart+intMiddle+intEnd
		End If

EXITPOINT:
		Exit Function
ERRHANDLE:
		Call LogError()
		Resume EXITPOINT
	End Function
End Class