Android Question Time and Countdown timer question

Hobby4Life

Member
Licensed User
Hello

I am struggling with a countdown timer.

I have created an app that divides 1 hour into 10 time slots of each 6 minutes.

Detecting which timeslot should be active is working using this piece of code.

I am detecting minutes and seconds.. Hours is not important..


In Activity create I set the global time format needed to show the complete clock "00:00:00"

B4X:
DateTime.TimeFormat = "HH:mm:ss"


With this I detect the timeslot we are in at DateTime.Now

B4X:
If TimeIsBetween(DateTime.Time(DateTime.Now),"00:00","06:00") =  True Then
        TimeSlot = 1
End If

and

B4X:
Sub TimeIsBetween(TimeBetween As String,t1 As String, t2 As String) As Boolean
    Dim OrigDateFormat As String = DateTime.dateFormat
    DateTime.dateFormat = "mm:ss"
    Dim tbetween As Long = DateTime.dateParse(sf.right(TimeBetween,5))
    Dim tstart As Long = DateTime.dateParse(t1)
    Dim tend As Long = DateTime.dateParse(t2)
    DateTime.dateFormat =OrigDateFormat
    If tbetween >= tstart And tbetween <= tend Then
        Return True
    Else
        Return False
    End If
End Sub

The strange thing is.. without using a Special Function (to cutoff the first 3 characters "00:") it compares it with Hours and Minutes.. instead of Minutes and Seconds..
While Dateformat is set to "mm:ss" in the function.

In the global scope I need the full format for correct displaying of my clock "00:00:00"


Another questios is how to create a countdown timer from 6:00 to 0:00 every time the Timeslot changes. According to DateTime.Now..

For Example when starting the app.. the countdown timer must start correctly according to DateTime.now..

example time is: 13:03:30 now the countdown clock must start at "02:30" counting down..

Or time is: 13:45:32 now the countdown clock must start at "02:28" and count down.

This is beyond my knowledge how to approach this.


For now I simply reset variables CD_Min to 6 and CD-Sec to 0 and let the timer decrement them at at timer interrupt.. but this only works at the beginning of a new timeslot.

Problem here I experienced that this frequently not is correctly compared to the Clock.. it stays behind of runs 1 or 2 seconds ahead.

B4X:
Sub CountDown
   
    If CounterActive = True Then
        If CD > 0 Then
            CD = CD - 1
            ProgressBar1.Progress = CD / 3.6
            CircularProgressBar1.Value = CD / 3.6
        End If

        If CD_Sec = 0 Then
            CD_Min = CD_Min - 1
            CD_Sec = 60
        End If
       
        If CD_Sec > 0 Then
            CD_Sec = CD_Sec - 1
        End If
       
        lblTimeLeft.Text = $"$2.0{CD_Min}:$2.0{CD_Sec}"$
       
        If CD_Min = 0 And CD_Sec = 0 Then
            CD_Min = 6
            CD_Sec = 0
        End If
    End If

End Sub

I would be very nice to have a library for these kind of timing functions. :)
 

emexes

Expert
Licensed User
I would do something like this:
B4X:
Dim SaveTimeFormat As String = DateTime.TimeFormat
DateTime.TimeFormat = "HH:mm:ss"
Dim Midnight As Long = DateTime.TimeParse("00:00:00")    '<-- this is the line that actually does something
DateTime.TimeFormat = SaveTimeFormat

Dim TimeOfDay As Long = DateTime.Now - Midnight    'milliseconds since midnight, ie maximum of 86,400 seconds = 86,400,000 milliseconds
 
Dim SixMinuteTimer As Int = TimeOfDay Mod 360000    'milliseconds within six-minute block ie 0 .. 360,000 milliseconds (360 seconds)
 
Dim MillisecondsRemaining As Int = 360000 - SixMinuteTimer    'milliseconds countdown 360,000 .. 0
 
Dim SecondsRemaining As Float = MillisecondsRemaining / 1000    'seconds countdown 360 .. 0
 
Log(DateTime.Time(DateTime.Now) & " " & SixMinuteTimer & " " & NumberFormat2(SecondsRemaining, 1, 1, 1, False))
I've split the calculation into small steps and interim variables so that hopefully it is clear(er) how it is done, but if you like having fewer-but-longer program lines then obviously you can merge the calculations together if you wish.

Also, you could probably just do the Midnight fetch once at program start. Even if there was a daylight savings jump, it will likely be an integer multiple of your six-minute period, and thus no problem. Ditto if your program runs more than one day.
 
Upvote 0

Hobby4Life

Member
Licensed User
That works great!, I have added it to my code as a sub. and called it in my timer_tick.. the log output looks precisely what i am looking for.
I have to understand the code a bit more.. but I can reverse engineer it back :)

Question, how can I put milleseconds back to a Time format? for example I want to display the SixMinuteTimer in a label als time.

--- EDIT ---

I Think I got it working :)

B4X:
    Dim MyOrigdate As String =DateTime.DateFormat
    DateTime.DateFormat ="mm:ss"
    Dim lngDate As Long= SecondsRemaining * 1000
    Dim strDate As String = DateTime.Date(lngDate)
    Log(strDate) 
    Debug_label.Text = strDate
    DateTime.DateFormat=MyOrigdate
 
Last edited:
Upvote 0
Top