calculate Time Due From a DateTime value in business hours (cont) - vb.net 2003

Hi Experts,

I have code which provides a time estimation based on 8 hours (between 08:00 - 19:00) Mon-Fri. ignoring sat/sun.

I wish to amend the code to provide a time estimation based on 5 working days.

The code below works for 8hours... I have tried to change the code myself (but I'm a bit thick).

I've tried changing:
dtReady = dtWantedAt.AddDays(1).Date
to
dtReady = dtWantedAt.AddDays(5).Date

But I can't seem to figure out how to do this. I tied the number 40 (based on 8x5) but this still didn't work.

Thanks,
Roberto

Code provided by MijaeDjinn.

Public Class Form1
    Function nextDOW(ByVal dow As DayOfWeek, ByVal dtmDate As Date) As Date
        ' Find the next specified day of the week    
        ' after the specified date.                    
        Dim numDays As Integer
        'sunday = 0
        If dtmDate.DayOfWeek > dow Then
            numDays = 7 - (dtmDate.DayOfWeek - dow)
        Else
            numDays = dow - dtmDate.DayOfWeek
        End If
 
        nextDOW = dtmDate.AddDays(numDays)
    End Function
 
    Private Function IsAfterHours(ByVal dt As DateTime, ByVal min As TimeSpan, ByVal max As TimeSpan) As Boolean
        If dt.Hour > max.Hours Then Return True
        If (dt.Hour = max.Hours) And (dt.Minute > max.Minutes) Then Return True
        If (dt.Hour < min.Hours) Then Return True
        If (dt.Hour = min.Hours) And (dt.Minute < min.Minutes) Then Return True
        Return False
    End Function
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim MaxTime As New TimeSpan(18, 0, 0)
        Dim MinTime As New TimeSpan(7, 59, 0)
        'Dim timeRemaining As TimeSpan
 
        Dim dtNow As DateTime = Now
        Dim dtWantedAt As DateTime = dtNow.AddHours(8)
 
        Dim dtReady As DateTime
 
        'calculate what day it will be ready
        If (dtWantedAt.DayOfWeek = DayOfWeek.Friday And _
            IsAfterHours(dtWantedAt, MinTime, MaxTime)) Or _
            (dtWantedAt.DayOfWeek = DayOfWeek.Saturday Or _
            dtWantedAt.DayOfWeek = DayOfWeek.Sunday) Then
            'will be ready on Monday
            dtReady = nextDOW(DayOfWeek.Monday, dtWantedAt).Date
        ElseIf IsAfterHours(dtWantedAt, MinTime, MaxTime) Then
            'will be ready tommorow
            dtReady = dtWantedAt.AddDays(1).Date
        Else
            'will be ready today
            dtReady = dtWantedAt.Date
        End If
 
        'calculate what time it will be ready
        Dim timeLeftToWait As New TimeSpan(8, 0, 0)
 
        If Not IsAfterHours(dtNow, MinTime, MaxTime) Then
            'requested during hours of operation
            If IsAfterHours(dtWantedAt, MinTime, MaxTime) Then
                'wanted outside of hours of operation
                timeLeftToWait = timeLeftToWait.Subtract(MaxTime.Subtract(dtNow.TimeOfDay))
                dtReady = dtReady.Add(timeLeftToWait.Add(MinTime))
            Else
                'wanted during hours of operation
                dtReady = dtReady.Add(dtWantedAt.TimeOfDay)
            End If
        Else
            'requested outside of hours of operation
            Console.WriteLine(timeLeftToWait.Hours)
            dtReady = dtReady.Add(MinTime.Add(timeLeftToWait))
        End If
 
        Label1.Text = "Current Time = " & dtNow.ToLongTimeString
        Label2.Text = "Your car will be ready on " & dtReady.ToLongDateString & " at " & dtReady.ToLongTimeString
 
    End Sub
End Class

Open in new window

RobertoFreemanoAsked:
Who is Participating?
 
Jeff CertainCommented:
Here's my take on a solution. It's a little more flexible -- you can give it any number of hours for your estimate.

I wasn't sure what your rules were around end-of-day issues, so there may be some invalid assumptions there. There's also duplicated code in here that could be pulled out into another method, but that's cleanup work.
Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim dtNow As DateTime = Now
        Dim calculator As New TimeCalculator
        Dim dtReady As DateTime = calculator.CalculateTime(dtNow, 40)
        Label1.Text = "Current Time = " & dtNow.ToLongTimeString
        Label2.Text = "Your car will be ready on " & dtReady.ToLongDateString & " at " & dtReady.ToLongTimeString
    End Sub
End Class

Public Class TimeCalculator
    ''' <summary>
    ''' goal is to add the number of hours to the current time
    ''' assuming work hours are Mon-Fri, 0800-1900
    ''' </summary>
    ''' <param name="currentTime"></param>
    ''' <param name="numberOfHours"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CalculateTime(ByVal currentTime As DateTime, ByVal numberOfHours As Integer) As DateTime
        Dim readyTime As DateTime = currentTime

        Select Case currentTime.DayOfWeek
            Case DayOfWeek.Saturday, DayOfWeek.Sunday
            Case Else
                ' this can be made cleaner, but we'll assume that the estimate isn't being made exactly on the hour
                Dim remainingHoursToday As Integer = 18 - currentTime.Hour
                If remainingHoursToday > 0 Then
                    With currentTime
                        readyTime = New DateTime(.Year, .Month, .Day, 8, 0, 0)
                    End With
                    readyTime = readyTime.AddDays(1)

                    ' adjust to skip the weekend
                    Select Case readyTime.DayOfWeek
                        Case DayOfWeek.Saturday
                            readyTime = readyTime.AddDays(2)
                        Case DayOfWeek.Sunday
                            readyTime = readyTime.AddDays(1)
                    End Select

                    numberOfHours -= remainingHoursToday
                End If
        End Select

        While numberOfHours > 0
            Select Case readyTime.DayOfWeek
                Case DayOfWeek.Saturday, DayOfWeek.Sunday
                    readyTime = readyTime.AddDays(1)
                Case Else
                    If numberOfHours > 11 Then
                        numberOfHours -= 11
                        readyTime = readyTime.AddDays(1)
                    Else
                        readyTime = readyTime.AddHours(numberOfHours)
                        numberOfHours = 0
                    End If
            End Select
        End While

        Return readyTime
    End Function
End Class

Open in new window

0
 
RobertoFreemanoAuthor Commented:
Sorry Chaosian, technical problems with my PC - will test as soon as ;)
0
 
RobertoFreemanoAuthor Commented:
Sorry Chaosian,

Will test tonight ;)
0
 
RobertoFreemanoAuthor Commented:
Thanks Chaosian ;)
0
 
Jeff CertainCommented:
Glad I could help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.