def __dayGenerator(self, unsafeDate, back): '''Генератор дней, используемый, если номер дня не фиксирован. @param unsafeDate: объект класса L{Unsafedate<utils.dates.UnsafeDate>}, задающий начальную дату @param back: если C{True}, поиск ведётся в направлении прошлого, иначе в направлении будущего @returns: Iterable по датам (объектам класса C{datetime.date}). Для взаимодействия с вышестоящим генератором Iterable может также возвращать C{None}. @see: L{__scan} ''' helper = self._DayGeneratorHelper.new(self, back) date, skip = self.__wrapDate_noFail(unsafeDate) nextDate = helper.checkWeekday(date) if date == nextDate and skip: nextDate = helper.step() while True: # Find a date satisfying both weekday and year-month-day conditions while date != nextDate: if date.month != nextDate.month: (year, month) = (yield None); yield None if year != nextDate.year or month != nextDate.month: date = datetime.date(year, month, 1) if not back \ else dateutils.lastDayOfMonth(year, month) nextDate = helper.checkWeekday(date) continue date = nextDate yield date nextDate = helper.step()
def __findStartDate(self, startDate, back): '''Найти первую дату, удовлетворяющую условиям. @param startDate: объект класса C{datetime.date}, задающий начальную дату для поиска @param back: если C{True}, поиск ведётся в направлении прошлого, иначе в направлении будущего @returns: объект класса L{UnsafeDate<utils.dates.UnsafeDate>} или C{None}, если подходящих дат не найдено ''' op = operator.lt if not back else operator.gt delta = 1 if not back else -1 month_start = 1 if not back else 12 month_end = 12 if not back else 1 class EmptyResult(Exception): pass def addYear(year): if self.year is None: return year + delta else: raise EmptyResult() def addMonth(year, month): if self.month is None: if month == month_end: return (addYear(year), month_start) else: return (year, month + delta) else: return (addYear(year), month) try: year = self.year if year is None: year = startDate.year elif op(year, startDate.year): return None atStartDate = (year == startDate.year) month = self.month if month is None: if atStartDate: month = startDate.month else: month = month_start elif op(month, startDate.month) and year == startDate.year: year = addYear(year) atStartDate = (year == startDate.year and month == startDate.month) day = self.day if day is None: if atStartDate: day = startDate.day else: day = 1 if not back else dateutils.lastDayOfMonth(year, month).day elif op(day, startDate.day) and atStartDate: (year, month) = addMonth(year, month) return dateutils.UnsafeDate(year, month, day) except EmptyResult: return None