Android Code Snippet [B4X] Calculating the next scheduled time

Discussion in 'Code Snippets' started by Erel, Mar 24, 2016.

  1. Erel

    Erel Administrator Staff Member Licensed User

    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.

    Code:
    Dim t As Long = FindNextTime(Array As Double(56.520))
    Log($"Next time is: $DateTime{t}"$)

    Sub FindNextTime(Times As ListAs Long
       Times.Sort(
    True)
       
    For Each st As Double In Times
         
    If SetHours(st) > DateTime.Now Then
           
    Return SetHours(st)
         
    End If
       
    Next
       
    Return DateTime.Add(SetHours(Times.Get(0)), 001)
    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: Dec 12, 2016
  2. somed3v3loper

    somed3v3loper Well-Known Member Licensed User

    And if I need for example 3:17
    Should I pass 3.28 ?
    I do not think it is very accurate
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    Pass 3 + 17/60. It is very very accurate.
     
    lemonisdead, somed3v3loper and RauchG like this.
  4. somed3v3loper

    somed3v3loper Well-Known Member Licensed User

    Code:
    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
     
  5. inakigarm

    inakigarm Well-Known Member Licensed User

    3+00/60=3+0

    3 or 15?
     
  6. Myr0n

    Myr0n Active Member Licensed User

    What time is it at your place?
     
  7. somed3v3loper

    somed3v3loper Well-Known Member Licensed User

    I know I mean why didn't it return 12:01
    10PM
     
  8. Myr0n

    Myr0n Active Member Licensed User

    ;)

    10pm = 22hrs
     
    mangojack likes this.
  9. somed3v3loper

    somed3v3loper Well-Known Member Licensed 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
     
    Last edited: Mar 27, 2016
  10. Myr0n

    Myr0n Active Member Licensed User

    It's ok probably you are tired o_O

    We are here to help each other ;) even if we are like this o_O at a moment :)

    Just remember we have only 24hrs, we would like to have more hours sometime, but we don't
     
    somed3v3loper likes this.
  11. somed3v3loper

    somed3v3loper Well-Known Member Licensed User

    I think it is relative :p I have 23
     
    DonManfred and JordiCP like this.
  12. anOparator

    anOparator Active Member Licensed User

    How would $"$Time{t}"$ be used to launch an event?
    I've tried
    Code:
    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.
    Thanks in advance
    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: Jul 5, 2016
  13. anOparator

    anOparator Active Member Licensed User

    Code:
    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: Jul 6, 2016
  14. Declan

    Declan Active Member Licensed 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:
    Code:
    #Region  Service Attributes
        
    #StartAtBoot: True
        
    #ExcludeFromLibrary: True
    #End Region

    Sub Process_Globals
        
    Dim t As Long = FindNextTime(Array As Double(71420))
        
    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 ListAs Long
       Times.Sort(
    True)
       
    For Each st As Double In Times
         
    If SetHours(st) > DateTime.Now Then
           
    Return SetHours(st)
         
    End If
       
    Next
       
    Return DateTime.Add(SetHours(Times.Get(0)), 001)
    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

    Sub Service_TaskRemoved
        
    '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 StringAs Boolean
        
    Return True
    End Sub

    Sub Service_Destroy

    End Sub
    I have a problem with this:
    Code:
    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:
    Code:
    Next time is07: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.app.ActivityThread.handleServiceArgs(ActivityThread.java:
    3128)
        at android.app.ActivityThread.access$
    2100(ActivityThread.java:178)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:
    1568)
        at android.os.Handler.dispatchMessage(Handler.java:
    111)
        at android.os.Looper.loop(Looper.java:
    194)
        at android.app.ActivityThread.main(ActivityThread.java:
    5637)
        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)
     
  15. Erel

    Erel Administrator Staff Member Licensed User

    Please don't make duplicate posts.
     
  16. Myr0n

    Myr0n Active Member Licensed User

    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
     
  17. Declan

    Declan Active Member Licensed User

  18. udg

    udg Expert Licensed 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:
    Code:
    t = FindNextTime(Array As Double(12+56/6012+57/6012+58/6012+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
    Code:
    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: Oct 12, 2016
  19. ilan

    ilan Expert Licensed 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?
     
    aeric likes this.
  20. udg

    udg Expert Licensed 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
     
    Myr0n and ilan like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice