summaryrefslogtreecommitdiffstats
path: root/Lib/calendar.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/calendar.py')
-rw-r--r--Lib/calendar.py72
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):
"""