diff options
Diffstat (limited to 'Lib/calendar.py')
-rw-r--r-- | Lib/calendar.py | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/Lib/calendar.py b/Lib/calendar.py index 0218e2d..fb594e0 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -126,6 +126,24 @@ def monthrange(year, month): return day1, ndays +def monthlen(year, month): + return mdays[month] + (month == February and isleap(year)) + + +def prevmonth(year, month): + if month == 1: + return year-1, 12 + else: + return year, month-1 + + +def nextmonth(year, month): + if month == 12: + return year+1, 1 + else: + return year, month+1 + + class Calendar(object): """ Base calendar class. This class doesn't do any formatting. It simply @@ -157,20 +175,20 @@ class Calendar(object): values and will always iterate through complete weeks, so it will yield dates outside the specified month. """ - date = datetime.date(year, month, 1) - # Go back to the beginning of the week - days = (date.weekday() - self.firstweekday) % 7 - date -= datetime.timedelta(days=days) - oneday = datetime.timedelta(days=1) - while True: - yield date - try: - date += oneday - except OverflowError: - # Adding one day could fail after datetime.MAXYEAR - break - if date.month != month and date.weekday() == self.firstweekday: - break + for y, m, d in self.itermonthdays3(year, month): + yield datetime.date(y, m, d) + + def itermonthdays(self, year, month): + """ + Like itermonthdates(), but will yield day numbers. For days outside + the specified month the day number is 0. + """ + day1, ndays = monthrange(year, month) + days_before = (day1 - self.firstweekday) % 7 + yield from repeat(0, days_before) + yield from range(1, ndays + 1) + days_after = (self.firstweekday - day1 - ndays) % 7 + yield from repeat(0, days_after) def itermonthdays2(self, year, month): """ @@ -180,17 +198,31 @@ class Calendar(object): for i, d in enumerate(self.itermonthdays(year, month), self.firstweekday): yield d, i % 7 - def itermonthdays(self, year, month): + def itermonthdays3(self, year, month): """ - Like itermonthdates(), but will yield day numbers. For days outside - the specified month the day number is 0. + Like itermonthdates(), but will yield (year, month, day) tuples. Can be + used for dates outside of datetime.date range. """ day1, ndays = monthrange(year, month) days_before = (day1 - self.firstweekday) % 7 - yield from repeat(0, days_before) - yield from range(1, ndays + 1) days_after = (self.firstweekday - day1 - ndays) % 7 - yield from repeat(0, days_after) + y, m = prevmonth(year, month) + end = monthlen(y, m) + 1 + for d in range(end-days_before, end): + yield y, m, d + for d in range(1, ndays + 1): + yield year, month, d + y, m = nextmonth(year, month) + for d in range(1, days_after + 1): + yield y, m, d + + def itermonthdays4(self, year, month): + """ + Like itermonthdates(), but will yield (year, month, day, day_of_week) tuples. + Can be used for dates outside of datetime.date range. + """ + for i, (y, m, d) in enumerate(self.itermonthdays3(year, month)): + yield y, m, d, (self.firstweekday + i) % 7 def monthdatescalendar(self, year, month): """ |