Tuesday, November 22, 2005

Convert Seconds to Countdown Time

I seem to find myself doing alot of “countdown” type app’s/features. For example, right now I’m working on a “ping this list of machines every ## minutes” control.

When I build these kinds of things, I like giving the user an idea when the next event will happen. Hence a countdown…

I have a timer set to a 1 second interval (Timer.Interval = 1000) and each tick I decrement the remaining seconds by one. When the remaining seconds hits zero I reset the remaining seconds to the master interval and fire off the “event” (which with VB/VS 2005, I’m using the BackgroundWorker component).

While the time is counting down, I like to give the user a Minutes:Seconds countdown. I find myself reinventing this wheel over and over. I’m creating a snippet now, but also wanted to post the code here…

This function will take in the seconds and return a “m:ss” string. For example, 119 will return “1:59”, 61 will return “1:01”, 59 will return “59”

It’s quick and dirty, but gets the job done.

Private Function ConvertSecondstoCountdownTime(ByVal Seconds As Integer) _
                    As String

    Dim Result As String
    Dim Minutes As Integer
    Dim RemainingSeconds As Integer

    If Seconds < 60 Then
      Result = Seconds.ToString

    Else

      Minutes = Seconds \ 60

      RemainingSeconds = Seconds - (Minutes * 60)

      If RemainingSeconds < 10 Then
        Result = String.Format("{0:G}:0{1:G}", Minutes, _
                                RemainingSeconds)
      Else
        Result = String.Format("{0:G}:{1:G}", Minutes, _
                                RemainingSeconds)

      End If

    End If

    Return Result

  End Function

3 comments:

  1. In your stated use case it very likely doesn't matter, but delays in the ui code "getting around" to firing the event, plus the level of precision in the timer itself, can lead to innaccuracies. One approach I have taken is to record the wall clock time when the countdown starts, and subtract it from the current time to get the difference. The minus operator for 2 DateTimes results in a TimeSpan result, which is even pretty handy for displaying what you are getting at.

    ReplyDelete
  2. Quick and dirty example - I am not a VB Coder

    Public Class Countdown
    Dim start As DateTime
    Dim length As TimeSpan

    Public Sub StartTimer(countdownLength as TimeSpan)
    start = DateTime.Now
    length = countdownLength
    End Sub

    Public Function GetRemaining() As TimeSpan
    Dim remaining As TimeSpan
    remaining = (length - (DateTime.Now - start))
    If (remaining.TotalSeconds < 1) Then
    remaining = TimeSpan.FromSeconds(0)
    End If
    Return remaining
    End Function

    Public Overrides Function ToString() As String
    Dim remaining As TimeSpan
    remaining = GetRemaining()
    Return String.Format("{0:G}:{1:G}", remaining.Minutes, remaining.Seconds)
    End Function

    End Class

    ReplyDelete
  3. You are very right... The Timer is "sloppy", but in my case it does okay.

    If truly accurate timing/intervals/etc are needed the Timer just isn't the right tool.

    Thanks for the code sample. Something for me to think about.

    I like the thought of using of DateTime and TimeSpan types...

    Thank you...

    ReplyDelete

NOTE: Anonymous Commenting has been turned off for a while... The comment spammers are just killing me...

ALL comments are moderated. I will review every comment before it will appear on the blog.

Your comment WILL NOT APPEAR UNTIL I approve it. This may take some hours...

I reserve, and will use, the right to not approve ANY comment for ANY reason. I will not usually, but if it's off topic, spam (or even close to spam-like), inflammatory, mean, etc, etc, well... then...

Please see my comment policy for more information if you are interested.

Thanks,
Greg

PS. I am proactively moderating comments. Your comment WILL NOT APPEAR UNTIL I approve it. This may take some hours...