[Tasker Tips & Tricks] Necromancer3:
I've done similar, with help from your code.

My query starts from the end of the day moving backwards (from midnight backwards to 6 AM), pushing new events to the start of an array (2nd array for saving the event time).

So the first event of the day ends up first in the array.

the query is set up for 15 min interval (900s).

Then run a for loop taking out the event and its time.

Using a separate task to convert the time into audible AM/PM time (aka introduction to subroutines)

Calendar# (284)
A1: Variable Convert [ Name:%DATE Function:Date Time to Seconds Store Result In:%start_time ]
A2: Variable Set [ Name:%index To:%start_time + (60*60*24) Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ]
A3: Variable Set [ Name:%end_time To:%start_time + (60*60*5) Recurse Variables:eek:ff Do Maths:eek:n Append:eek:ff ]
A4: Variable Set [ Name:%index To:%index - 900 Recurse Variables:eek:ff Do Maths:eek:n Append:eek:ff ]
A5: Test App [ Type:Calendar Title Data:%index Store Result In:%events ]
A6: For [ Variable:%event Items:%events(:) ]
A7: If [ %arr1 Set ]
<new event (not duplicate)>
A8: If [ %arr(>) !~ %event ]
<save event in arr if not duplicate>
A9: Array Push [ Variable Array:%arr Position:1 Value:%event Fill Spaces:eek:ff ]
<save event time in arr if not duplicate>
A10: Array Push [ Variable Array:%arr_time Position:1 Value:%index Fill Spaces:eek:ff ]
<duplicate event>
A11: Else
<update event start time>
A12: Variable Set [ Name:%arr_time1 To:%index Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ]
A13: End If
A14: Else
A15: Array Push [ Variable Array:%arr Position:1 Value:%event Fill Spaces:eek:ff ]
A16: Array Push [ Variable Array:%arr_time Position:1 Value:%index Fill Spaces:eek:ff ]
A17: End If
A18: End For
A19: Goto [ Type:Action Number Number:4 Label: ] If [ %index > %end_time ]
A20: Say [ Text:No events today Engine:Voice:com.google.android.tts:eng-usa Stream:3 Pitch:5 Speed:5 Respect Audio Focus:eek:n Network:eek:ff Continue Task Immediately:eek:ff ] If [ %arr(#) eq 0 ]
A21: [X] Flash [ Text:There are no events today Long:eek:ff ] If [ %arr(#) eq 0 ]
A22: Say [ Text:eek:ne event Engine:Voice:com.google.android.tts:eng-usa Stream:3 Pitch:5 Speed:5 Respect Audio Focus:eek:n Network:eek:ff Continue Task Immediately:eek:ff ] If [ %arr(#) eq 1 ]
A23: [X] Flash [ Text:There is one event Long:eek:ff ] If [ %arr(#) eq 1 ]
A24: Say [ Text:%arr(#) events Engine:Voice:com.google.android.tts:eng-usa Stream:3 Pitch:5 Speed:5 Respect Audio Focus:eek:n Network:eek:ff Continue Task Immediately:eek:ff ] If [ %arr(#) > 1 ]
A25: [X] Flash [ Text:There are %arr(#) events Long:eek:ff ] If [ %arr(#) > 1 ]
A26: For [ Variable:%index Items:1:%arr(#) ] If [ %arr(#) > 0 ]
A27: Variable Set [ Name:%time To:%arr_time(%index) Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ]
A28: Perform Task [ Name:Time24To12 Priority:%priority+1 Parameter 1 (%par1):%time Parameter 2 (%par2): Return Value Variable:%time Stop:eek:ff ]
A29: Variable Split [ Name:%time Splitter:| Delete Base:eek:ff ]
A30: Say [ Text:%arr(%index) at %time1 %time2 %time3 Engine:Voice:com.google.android.tts:eng-usa Stream:3 Pitch:5 Speed:5 Respect Audio Focus:eek:n Network:eek:ff Continue Task Immediately:eek:ff ]
A31: [X] Flash [ Text:%arr(%index) at %time1 %time2 %time3 Long:eek:ff ]
A32: End For

Time24To12 (278)
A1: [X] Variable Convert [ Name:%DATE Function:Date Time to Seconds Store Result In:%index ]
A2: [X] Variable Set [ Name:%index To:%index + (60*60*6) Recurse Variables:eek:ff Do Maths:eek:n Append:eek:ff ]
A3: Variable Set [ Name:%index To:%par1 Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ]
A4: Variable Convert [ Name:%index Function:Seconds to Date Time Store Result In:%time ]
A5: Variable Set [ Name:%space To: Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ]
A6: Variable Split [ Name:%time Splitter:%space Delete Base:eek:ff ]
A7: Variable Set [ Name:%time To:%time2 Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ]
A8: Variable Split [ Name:%time Splitter:. Delete Base:eek:ff ]
A9: [X] Flash [ Text:%time1 Long:eek:ff ]
A10: Variable Set [ Name:%ttime To:%time1-12 Recurse Variables:eek:ff Do Maths:eek:n Append:eek:ff ]
A11: Variable Set [ Name:%time1 To:%ttime Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ] If [ %ttime > 0 ]
A12: Variable Set [ Name:%time1 To:%time1/1 Recurse Variables:eek:ff Do Maths:eek:n Append:eek:ff ]
A13: Variable Set [ Name:%time2 To:%time2/1 Recurse Variables:eek:ff Do Maths:eek:n Append:eek:ff ]
A14: Variable Set [ Name:%time2 To: Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ] If [ %time2 eq 0 ]
A15: Variable Set [ Name:%time2 To:o %time2 Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ] If [ %time2 < 10 ]
A16: Variable Set [ Name:%AM_PM To:PM Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ] If [ %ttime > 0 ]
A17: Variable Set [ Name:%AM_PM To:PM Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ] If [ %ttime = 0 ]
A18: Variable Set [ Name:%AM_PM To:AM Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ] If [ %ttime < 0 ]
A19: Variable Set [ Name:%result To:%time1|%time2|%AM_PM Recurse Variables:eek:ff Do Maths:eek:ff Append:eek:ff ]
A20: Return [ Value:%result Stop:eek:n ]
A21: [X] Flash [ Text:%result Long:eek:ff ]