# - - - B i r d N o t e S e t . _ t i m e F i l t e r def _timeFilter(self, monthKey, startDate, endDate, startSeason, endSeason): '''Does this month contain records of interest? [ (monthKey is a month name as "YYYY-MM") and (startDate is an inclusive starting date as a datetime.date, or None for no starting cutoff) and (endDate is an inclusive ending date as a datetime.date or None for no ending cutoff) and (startSeason is an inclusive starting month and day as a datetime.date or None for no starting cutoff) and (endSeason is an inclusive ending month and day as a datetime.date or None for no ending cutoff) -> if monthKey's month might contain records in those date and day-of-year ranges -> return True else -> return False ] '''
First we must set up two
instances representing the limits of
monthKey's month. Rather than have to worry
about the date of the last day of each month, we use a
half-open interval [
firstOfNext) where the interval includes the
first day of the month, but does not include the first
day of the following month (which is easier to compute).
#-- 1 -- # [ firstOfThis := a datetime.date instance representing # the first day of monthKey's month # firstOfNext := a datetime.date instance representing # the first day of the month following monthKey ] #-- # NB: Positions within a YYYY-MM string: # 0 1 2 3 4 5 6 7 # Y Y Y Y - M M #-- yyyy = int(monthKey[:4]) mm = int(monthKey[5:]) firstOfThis = datetime.date(yyyy, mm, 1) if mm==12: firstOfNext = datetime.date(yyyy+1, 1, 1) else: firstOfNext = datetime.date(yyyy, mm+1, 1)
The selection logic is straightforward. When one of the limit
None, there is no cutoff at that
limit. Where there is a cutoff, we can use the handy property
that the normal comparison operators work on
startDate is on or after
monthKey is too
endDate is before
monthKey is too late.
#-- 2 -- if((startDate is not None) and (startDate >= firstOfNext)): return False #-- 3 -- if((endDate is not None) and (endDate < firstOfThis)): return False
To test for the correct month without regard to the
year, we use the
to create copies of the supplied
endSeason with the year changed to
yyyy. Each copy is then compared to the half-open
firstOfNext) as above.
#-- 4 -- if startSeason is not None: start = startSeason.replace(yyyy) if start >= firstOfNext: return False #-- 5 -- if endSeason is not None: end = endSeason.replace(yyyy) if end < firstOfThis: return False #-- 6 -- return True