Here's my attempt at a general routine...I hope it helps you get where you want to be
(P.S. PB 4.02)
Code: Select all
; -------------------------------------------------------------------------------------------------------
;
; PURPOSE:
; Date / time interval checking routines.
;
;
; CREATED:
; Techie42, 20th July 2007.
;
;
; NOTES:
; (i) This only works for dates AFTER 1st January 1970 (up to 2034),
; due to the way in which the "Date()" function works.
; (ii) This will only work for time intervals that span the same day
; (i.e. it will not work for intervals starting before midnight and ending after midnight)
;
; LICENSE:
; Do with this as you wish, in any manner, either privately or commercially.
; This is for general public consumption without any limitations.
; The original author will not, and cannot, be held responsible for any issues arising
; out of the use of this code.
;
;
; USAGE:
; (i) Define the linked list which contains the time ranges, as many as required, without overlapping ranges
; (ii) Define a variable to contain the return values, if any
; (iii) Call "checkInterval" to test a given time against the ranges
; (iv) If successful, populate the variable from step (ii) with the relevant values
; (v) Return True if a range is found, else return False
;
; -------------------------------------------------------------------------------------------------------
; Always ensure variables are explicitly declared
EnableExplicit
; Define the structure we will use to hold time ranges
Structure timeInterval
intervalTag.s ; The name of the range i.e. "Mid-Day"
intervalBegin.s ; The range starting time i.e. "12:15"
intervalEnd.s ; The range ending time i.e "14:30"
EndStructure
;
; PROCEDURE:
; checkInterval
;
; This routine checks the time ranges defined in the linked list to see if there is a match
; with a given time
;
; PARAMETERS:
; checkInterval( linkedList <required>, *returnItem <required>, timeToCheck <optional> )
;
; linkedList This should be of the type "timeInterval", and is populated with the
; time ranges you wish to check
;
; *returnItem This pointer to a variable of type "timeInterval" is used to supply
; the return values, if relevant i.e. a match is found
;
; timeToCheck If present, this is a time in the format "hh:mm"
; If not supplied, then the current computer time is used
;
Procedure.l checkInterval(intervalList.timeInterval(), *returnItem.timeInterval, timeCheck.s = "NOW")
Protected returnState.l ; The value returned from this procedure
Protected currentTimeIndex.l ; The time to check, either supplied or computer time
Protected intervalBegin.l ; Will hold the range starting time
Protected intervalEnd.l ; Will hold the range ending time
Protected saveIndex.l ; Let's be helpful and save the list index for the linked list
; so that we can restore the linked list index to the same position
; once we have finished walking the list
Protected bDone.l ; Boolean flag for indicating the end of a loop
; Ensure we have something in the linked list and something as the time to test...
If (intervalList() And (Len(Trim(timeCheck)) > 0))
; Make sure there are some items in the linked list...
If (CountList(intervalList()) > 0)
; If the time to test is not supplied, then the default value of "NOW" is used, so we
; will use the current computer time...otherwise we break the supplied time into
; hours and minutes...and convert this into the number of seconds since 1st January 1970...
If (timeCheck = "NOW")
currentTimeIndex = Date()
Else
currentTimeIndex = Date(Year(Date()), Month(Date()), Day(Date()), Val(StringField(timeCheck, 1, ":")), Val(StringField(timeCheck, 2, ":")), 0)
EndIf
; Ensure the time (supplied or otherwise) is actually valid...
If (currentTimeIndex <> -1)
bDone = #False
; Remember the current list index for restoration later on...
saveIndex = ListIndex(intervalList())
; We want to walk the linked list, so start at the beginning...
ResetList(intervalList())
; Process all linked list items until we either run out, or we have found a match...
While (NextElement(intervalList()) And (Not bDone))
; Get the range starting and ending times in the correct format...
; ...the number of seconds since 1st January 1970...
intervalBegin = Date(Year(Date()), Month(Date()), Day(Date()), Val(StringField(intervalList()\intervalBegin, 1, ":")), Val(StringField(intervalList()\intervalBegin, 2, ":")), 0)
intervalEnd = Date(Year(Date()), Month(Date()), Day(Date()), Val(StringField(intervalList()\intervalEnd, 1, ":")), Val(StringField(intervalList()\intervalEnd, 2, ":")), 0)
; Test to see if the currently selected range encompasses the required time check...
If ((intervalBegin <= currentTimeIndex) And (currentTimeIndex <= intervalEnd))
; If so, then let's return something useful, and indicate the process was successful...
*returnItem\intervalTag = intervalList()\intervalTag
*returnItem\intervalBegin = intervalList()\intervalBegin
*returnItem\intervalEnd = intervalList()\intervalEnd
bDone = #True
EndIf
Wend
; Be tidy and leave the linked list as we found it...
SelectElement(intervalList(), saveIndex)
; If we found a match, return True, else return False...
returnState = bDone
Else
; If there is no match, or something is invalid, we return False...
returnState = #False
EndIf
Else
; There were no items in the linked list...
returnState = #False
EndIf
Else
; One or more of the parameters were invalid...probably...
returnState = #False
EndIf
; Return the state...
ProcedureReturn returnState
EndProcedure
; This procedure is just to show how one procedure can call checkInterval, passing the relevant parameters.
; This is to avoid using Global variables.
Procedure.l main(timeCheck.s = "")
Protected returnState.l
; This is our linked list containing the time ranges...
Protected NewList intervalList.timeInterval()
; This is our item which will contain the return values, if available...
Protected returnItem.timeInterval
; Let's add three elements to the linked list...
AddElement(intervalList())
intervalList()\intervalTag = "Morning"
intervalList()\intervalBegin = "06:50"
intervalList()\intervalEnd = "08:30"
AddElement(intervalList())
intervalList()\intervalTag = "Mid-Day"
intervalList()\intervalBegin = "12:15"
intervalList()\intervalEnd = "14:30"
AddElement(intervalList())
intervalList()\intervalTag = "Afternoon"
intervalList()\intervalBegin = "17:10"
intervalList()\intervalEnd = "19:50"
; If we have supplied a time, then supply the time to checkInterval, otherwise leave out the parameter...
If (Len(Trim(timeCheck)) > 0)
returnState = checkInterval(intervalList(), returnItem, timeCheck)
Else
returnState = checkInterval(intervalList(), returnItem)
EndIf
; If the return value is True, then we have a match, so display the range values...
If (returnState)
Debug "Match :" + returnItem\intervalTag + " , " + returnItem\intervalBegin + " , " + returnItem\intervalEnd
Else
Debug "No matching time range."
EndIf
ProcedureReturn returnState
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++
main() ; First time through...use the default computer time...
main("12:27") ; Second time through...let's supply our own time...
End