Search code examples
vb.nettimetimerbasic

VB TimeFormat, timespan, current time


First i check if the time is in range 7:50 to 8:35 if is, in label show's message "1st Class in progress"

from 7:50 to 8:35 i have 45 minutes, like a school class.

In textbox i want to show how many time till class end.

Example if show's me the current time is 8:10 . In textbox it needs to show 25:00 ( which means 25 minutes till class end)

Current progress

 Private curT As DateTime
 curT = DateTime.Now
 If (curT.Hour = 7 And curT.Minute > 50) Or (curT.Hour = 8 And curT.Minute <= 35) Then
        lblPeriod.Text = "1st Class in progress "

i tried using timespan

 Dim first As DateTime = CDate("07:50")
        Dim second As DateTime = CDate("08:35")

        Dim current As DateTime
        current = DateTime.Now

        Dim diffBefore As TimeSpan = current - first
        Dim diffAfter As TimeSpan = second - current

        txtPassed.Text = diffBefore.ToString("mm\:ss")
        txtLeft.Text = diffAfter.ToString("mm\:ss")

But in txtleft it doesn't countdown to 00:00 ..

Is there any easier way to do this because i have 12 different "school classes"


Solution

  • I might use a class to track something like this (divining what you want to do from how you are trying to do it). A class would allow you to internalize some of the TimeSpan stuff, define class start/stops in one place and associate it with a Period/Class name rather than having them littering the code everywhere.

    Public Const PeriodLength = 40
    
    Friend Class ClassPeriod
        Public Property Name As String
    
        ' as implemented, these could be private and used internally only
        ' But they are props you might need elsewhere
        Public Property StartTime As TimeSpan
        Public Property EndTime As TimeSpan
    
        Public Sub New(txt As String, stHr As Integer, stMin As Integer)
            Name = txt
            ' internalize the Timespan objects
            StartTime = New TimeSpan(stHr, stMin, 0)
            ' calc end time from start time
            EndTime = StartTime.Add(New TimeSpan(0, PeriodLength, 0))
        End Sub
    
        ' use a status text return...kind of geared solely for this use though
        Public Function GetStatus() As String
            Dim thisTime = New TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, 0)
    
            If ((thisTime >= StartTime) AndAlso (thisTime <= EndTime)) Then
                Return String.Format("[{0}] In Session", Name)
            End If
    
            If (thisTime > StartTime) Then
                Return String.Format("[{0}] Ended", Name)
            End If
    
            If (thisTime < StartTime) Then
                Return String.Format("[{0}] starts in {1:hh\:mm} m", Name,
                             (StartTime - thisTime))
                ' StartTime.Subtract(thisTime) results in the same thing... 
                ' VB compiles the above to TS.Subtract
            End If
    
            ' might never show up since we dont test for betweens
            Return "Between Classes"
    
        End Function
    
        Public Overrides Function ToString() As String
            Return Name
        End Function
    End Class
    

    Now, a collection to hold the definitions. The names can be "1st Period"... for a generic "school level" tracker, or "Computer Science 101" if used by different students.

    Friend mySched As New List(Of ClassPeriod)
    

    Then populate it:

    Dim myClPer As ClassPeriod
    
    myClPer = New ClassPeriod("First Period", 7, 0)
    mySched.Add(myClPer)
    myClPer = New ClassPeriod("Computer Science", 7, 50)
    mySched.Add(myClPer)
    
    ' or add as you make them:
    mySched.Add(New ClassPeriod("Meaning of Life", 8, 40))
    mySched.Add(New ClassPeriod("Visual Basic 602", 9, 40))   ' ???
    

    (I dont know that all your times are correct, or that I fished the right ones out, but that is not the point, they are easily changed in one spot). Now, to display the classes status just go thru the list:

    lblPeriod1.Text = mySched(1).GetStatus()
    lblPeriod2.Text = mySched(2).GetStatus()
    lblPeriod4.Text = mySched(3).GetStatus()
    

    If you stored the label names in a list, you could just iterate:

    For n As Integer = 0 To mySched.Count - 1
        Controls(lblNames(n)).Text = mySched(n).GetStatus()
    Next n
    

    The GetStatus() would be better as an Enum if the return will ever be evaluated in code. I would avoid testing a String (If ..GetStatus() = "Ended"):

    Friend PeriodStatus
       InProgress
       Ended
       Pending
    End Enum
    

    The existing GetStatus could then become GetStatusText for formatting and displaying info to the user. The result with a button click standing in for a Timer, a listbox for a bunch of labels:

    enter image description here

    Works on My SystemTM