Android Code Snippet[B4X] Calculating the next scheduled time

Name: Find the next scheduled time.

Description by example: You need to start a service each day at 5 am, 6:30 am and 8 pm. You need to find the ticks values of the next scheduled time, either today or tomorrow if it is after 8pm.

B4X:
``````Dim t As Long = FindNextTime(Array As Double(5, 6.5, 20))
Log(\$"Next time is: \$DateTime{t}"\$)

Sub FindNextTime(Times As List) As Long
Times.Sort(True)
For Each st As Double In Times
If SetHours(st) > DateTime.Now Then
Return SetHours(st)
End If
Next
End Sub

Sub SetHours(st As Double) As Long
Dim hours As Int = Floor(st)
Dim minutes As Int = Round(60 * (st - hours))
Return DateUtils.SetDateAndTime(DateTime.GetYear(DateTime.Now), _
DateTime.GetMonth(DateTime.Now), DateTime.GetDayOfMonth(DateTime.Now), hours, minutes, 0)
End Sub``````

Last edited:

somed3v3loper

Well-Known Member
Longtime User
And if I need for example 3:17
Should I pass 3.28 ?
I do not think it is very accurate

Erel

B4X founder
Staff member
Longtime User
Pass 3 + 17/60. It is very very accurate.

somed3v3loper

Well-Known Member
Longtime User
B4X:
``FindNextTime(Array As Double(12+01/60,3+00/60))``
Can some one explain why does this code return 3:00 ?
When time is before both

Longtime User
3+00/60=3+0

3 or 15?

Myr0n

Active Member
Longtime User
B4X:
``FindNextTime(Array As Double(12+01/60,3+00/60))``
Can some one explain why does this code return 3:00 ?
When time is before both

What time is it at your place?

Longtime User

Longtime User

10pm = 22hrs

somed3v3loper

Well-Known Member
Longtime User

10pm = 22hrs
Right but shouldn't FindNextTime choose 12:01 which is 00:01 ?
Why did it skip 12 and chose 03:00 ? Aren't 12AM and 03AM supposed to be next day and 12AM is first ?'

Sorry for my stupid mistake
To explain : I thought 12 is like when we say 10 or 9 or any AM time
I should've typed 00:01

Last edited:

Myr0n

Active Member
Longtime User
Right but shouldn't FindNextTime choose 12:01 which is 00:01 ?
Why did it skip 12 and chose 03:00 ? Aren't 12AM and 03AM supposed to be next day and 12AM is first ?'

Sorry for my stupid mistake
To explain : I thought 12 is like when we say 10 or 9 or any AM time
I should've typed 00:01

It's ok probably you are tired

We are here to help each other even if we are like this at a moment

Just remember we have only 24hrs, we would like to have more hours sometime, but we don't

somed3v3loper

Well-Known Member
Longtime User
It's ok probably you are tired

We are here to help each other even if we are like this at a moment

Just remember we have only 24hrs, we would like to have more hours sometime, but we don't
I think it is relative I have 23

anOparator

Active Member
Longtime User
How would \$"\$Time{t}"\$ be used to launch an event?
I've tried
B4X:
``````Sub Service_Start(...)
If DateTime.Time(DateTime.Now) = \$"\$Time{t}"\$ Then
CallSub(Main, "Label2_Click")
End If
End Sub``````
among other things but I need help from there. This
calculate snippet is very handy.
edit:
Just found 'Comparing the system time as a string, Jan. 2014'.
Am wondering, Since this tracks the System time, is it Not heavy on the CPU.

Last edited:

anOparator

Active Member
Longtime User
How would \$"\$Time{t}"\$ be used to launch an event?
I've tried
B4X:
``````Sub Service_Start(...)
If DateTime.Time(DateTime.Now) = \$"\$Time{t}"\$ Then
CallSub(Main, "Label2_Click")
End If
End Sub``````
among other things but I need help from there. This
calculate snippet is very handy.
edit:
Just found 'Comparing the system time as a string, Jan. 2014'.
Am wondering, Since this tracks the System time, is it Not heavy on the CPU.
B4X:
``````Dim now = DateTime.Time(DateTime.Now) As String

Sub Service_Start(...)
If now => \$"\$Time{t}"\$ Then
Log ("The current time is: " & now)
Log("Next start time is : "  \$Time{t}"\$
CallSubDelayed(Main, "Button1_  Click")
Else
Log(" the time now is: " & now)
Log("the next start time is : " \$Time{t}"\$)
CallSubDelayed(Main, "Button2_Click")
End If
End Sub``````
Now, to launch the event at \$" \$Time{t}"\$

Last edited:

Declan

Well-Known Member
Longtime User
I am using a slightly edit version of the above examples:
I need to CallSubDelayed at 7:00am, 2:00pm and 8:00pm.
My Service:
B4X:
``````#Region  Service Attributes
#StartAtBoot: True
#ExcludeFromLibrary: True
#End Region

Sub Process_Globals
Dim t As Long = FindNextTime(Array As Double(7, 14, 20))
Log(\$"Next time is: \$Time{t}"\$)
Dim now = DateTime.Time(DateTime.Now) As String
End Sub

Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
If now = \$"\$Time{t}"\$ Then
Log ("The current time is: " & now)
Log(\$"Next time is: \$Time{t}"\$)
'        CallSubDelayed(Main, "ActionPop")
Else
Log(" the time now is: " & now)
Log(\$"Next time is: \$Time{t}"\$)
'     Do Nothing
End If

End Sub

Sub FindNextTime(Times As List) As Long
Times.Sort(True)
For Each st As Double In Times
If SetHours(st) > DateTime.Now Then
Return SetHours(st)
End If
Next
End Sub

Sub SetHours(st As Double) As Long
Dim hours As Int = Floor(st)
Dim minutes As Int = 60 * (st - hours)
Return DateUtils.SetDateAndTime(DateTime.GetYear(DateTime.Now), _
DateTime.GetMonth(DateTime.Now), DateTime.GetDayOfMonth(DateTime.Now), hours, minutes, 0)
End Sub

'This event will be raised when the user removes the app from the recent apps list.
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
Return True
End Sub

Sub Service_Destroy

End Sub``````

I have a problem with this:
B4X:
``````Sub Service_Start (StartingIntent As Intent)
If now = \$"\$Time{t}"\$ Then
Log ("The current time is: " & now)
Log(\$"Next time is: \$Time{t}"\$)
'        CallSubDelayed(Main, "ActionPop")
Else
Log(" the time now is: " & now)
Log(\$"Next time is: \$Time{t}"\$)
'     Do Nothing
End If

End Sub``````

I receive the following error in the debug log:
B4X:
``````Next time is: 07:00:00
** Service (starter) Create **
** Service (starter) Start **
Error occurred on line: 24 (Starter)
java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
at anywheresoftware.b4a.debug.RDebugUtils.solveBoolean(RDebugUtils.java:134)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:708)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:337)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at b4a.example.starter.handleStart(starter.java:101)
at b4a.example.starter.onStartCommand(starter.java:69)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit\$MethodAndArgsCaller.run(ZygoteInit.java:959)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)``````

Staff member
Longtime User

Myr0n

Active Member
Longtime User
I am using a slightly edit version of the above examples:
[/CODE]

I did a copy paste of your code to a new project, I added dbutils library to my project I ran the project and I did not have any errors.

This is my log

Next time is: 07:00:00
** Service (starter) Create **
** Service (starter) Start **
the time now is: 06:32:07
Next time is: 07:00:00
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **

Probably you are including something else in your code

Declan

Well-Known Member
Longtime User
@Myron - many thanks.
This has progressed somewhat, please see:

udg

Expert
Longtime User
Hi all,
today I started experimenting with a reminder app, so this thread sounded a good starting point.
So far I have the Starter service that starts my Reminder service (later I'll set Starter as #StartAtBoot) which in its Service_Start has the following:
B4X:
``t = FindNextTime(Array As Double(12+56/60, 12+57/60, 12+58/60, 12+59/60))``

the effect is that (surprisingly) it gets started at 12:56 , 12:58 and then programmed for tomorrow at 12:56.

Could it be that rounding plays a role in "skipping" some schedules? Should we modify
B4X:
``Dim minutes As Int = 60 * (st - hours)  'original``
in some way?

Note: I plan to record schedule times as strings formatted as "HH:mm", so my question is rised just to better understand the original code and its eventual limits of proper usage.

udg

Last edited:

ilan

Expert
Longtime User
Ok now this is something new to me.

B4x can use an array as double as a list?
Will it work for any array?

udg

Expert
Longtime User
Hi Ilan,
from the List definition:
"Lists are similar to dynamic arrays. You can add and remove items from a list and it will change its size accordingly.
A list can hold any type of object. However if a list is declared as a process global object it cannot hold activity objects (like views).
Basic4android automatically converts regular arrays to lists. So when a List parameter is expected you can pass an array instead."

udg

Replies
99
Views
6K
Replies
0
Views
578
Replies
1
Views
2K
Replies
36
Views
83K
Replies
106
Views
91K