Working with Python Calendar in Depth

Working with date and time data is common and essential for programmers, especially for those engaged in web or android development. So many times, you must have seen calendars on a website or android application, like for selecting your Date of Birth. In python, all these are possible using the python calendar module. 

If you have worked in Linux, use must be familiar with the ‘cal’ command. Python calendar module has a calendar class using which we can perform various calculations based on date, month, or year. Not only this, but we also have HTMLCalendar and TextCalendar class that allows us to edit the calendar and use it as per our requirements.  

Syntax- 

The calendar is a built-in module, so for using it, we just need to import it. To import use – ‘import calendar.’ Many operations can be performed using the calendar module, which we will learn one by one.  

Different Classes of python calendar module- 

Calendar (python calendar module)

Calendar class of calendar module creates an object which can be used for formatting. It has only one parameter, firstweekday, whose value by default is set to 0 (‘MONDAY’). For SUNDAY, set the value to 6.  

iterweekdays()It returns the day of the week, which is currently set as the first day. For Monday its ‘0’.
itermonthdates(yearmonth)It returns an iterator, which shows all the days of the month and some days of the previous month and next month which are required to complete the week.
itermonthdays2(yearmonth)It returns an iterator, which gives tuple as output which contains the days of the week from 0-6 with a day of the month.
Sample Output- (16, 3).
itermonthdays3(yearmonth)It is an upgraded version of itermonth2 and returns a tuple containing (year, month, day of the month).
Sample output- (2020, 7, 29)
itermonthdays4(yearmonth)It returns an iterator containing tuple in the given form- (year, month, day of the month, day of the week).
For example- (2020, 7, 21, 1)
monthdays2calendar(yearmonth)It returns a list containing containing tuples in the form (day of the month,day of the week) for the given month of the year.
monthdayscalendar(yearmonth)It returns a list containing the days of the month and some days of previous month and next month completing the week.
yeardays2calendar(year)The output is in the form of a list containing a tuple -(day of the month, day of the week) for the complete specified year.

TextCalendar(firstweekday):

Returns the plain calendar for the whole year, or for a particular month.  

formatmonth(theyearthemonth)Returns a calendar for the given year and month.
formatyear(year)It returns the calendar for the whole year.

HTMLCalendar( firstweekday)

It prints the calendar of a month in HTML format.

Program-

import calendar

cal=calendar.HTMLCalendar(0)
cal.formatmonth(2019,6)
'<table border="0" cellpadding="0" cellspacing="0" class="month">\n<tr><th colspan="7" class="month">June 2019</th></tr>\n<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>\n<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sat">1</td><td class="sun">2</td></tr>\n<tr><td class="mon">3</td><td class="tue">4</td><td class="wed">5</td><td class="thu">6</td><td class="fri">7</td><td class="sat">8</td><td class="sun">9</td></tr>\n<tr><td class="mon">10</td><td class="tue">11</td><td class="wed">12</td><td class="thu">13</td><td class="fri">14</td><td class="sat">15</td><td class="sun">16</td></tr>\n<tr><td class="mon">17</td><td class="tue">18</td><td class="wed">19</td><td class="thu">20</td><td class="fri">21</td><td class="sat">22</td><td class="sun">23</td></tr>\n<tr><td class="mon">24</td><td class="tue">25</td><td class="wed">26</td><td class="thu">27</td><td class="fri">28</td><td class="sat">29</td><td class="sun">30</td></tr>\n</table>\n'

Some Common programs using calendar module

Printing a calendar for a particular Year 

Using the calendar class of calendar module, we can print the calendar of any year. 

import calendar
year=int(input()) 
print(calendar.calendar(year))   
2019
python calendar

To print a particular month of a year using python calendar module

year=int(input()) 
month=int(input()) 
print (calendar.month(year,month))   
2020
2
   February 2020
Mo Tu We Th Fr Sa Su
                1  2
 3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29

In the above two outputs, you must have noticed that the calendar is starting from MONDAY. If we want to change it to any other month, suppose SUNDAY, let us see how we can do that. 

# Using the TextCalendar class
#Storing the TextCalendar object with starting day as Sunday in 'c' variable 
c=calendar.TextCalendar(calendar.SUNDAY)
# Calendar for year 2020
cal=c.formatyear(2020)
print(cal)

To print all the months of a year- 

for i in calendar.month_name: 
    print(i) 
January
February
March
April
May
June
July
August
September
October
November
December

Print (year, month, day of the month, day of the week) 

import calendar
c=calendar.TextCalendar(calendar.SUNDAY)
for i in c.itermonthdays4(2020,7): 
     print(i) 
(2020, 6, 29, 0)
(2020, 6, 30, 1)
(2020, 7, 1, 2)
(2020, 7, 2, 3)
(2020, 7, 3, 4)
(2020, 7, 4, 5)
(2020, 7, 5, 6)
(2020, 7, 6, 0)
(2020, 7, 7, 1)
(2020, 7, 8, 2)
(2020, 7, 9, 3)
(2020, 7, 10, 4)
(2020, 7, 11, 5)
(2020, 7, 12, 6)
(2020, 7, 13, 0)
(2020, 7, 14, 1)
(2020, 7, 15, 2)
(2020, 7, 16, 3)
(2020, 7, 17, 4)
(2020, 7, 18, 5)
(2020, 7, 19, 6)
(2020, 7, 20, 0)
(2020, 7, 21, 1)
(2020, 7, 22, 2)
(2020, 7, 23, 3)
(2020, 7, 24, 4)
(2020, 7, 25, 5)
(2020, 7, 26, 6)
(2020, 7, 27, 0)
(2020, 7, 28, 1)
(2020, 7, 29, 2)
(2020, 7, 30, 3)
(2020, 7, 31, 4)
(2020, 8, 1, 5)
(2020, 8, 2, 6)

Note- It prints (year, month, day of the month, day of the week) for a month and some days of the previous month and next month to complete the weeks. 

To check if a year is a leap year or not using python calendar module

import calendar

def isleapyear(year):
    return calendar.isleap(year)

print(isleapyear(2012))
print(isleapyear(2021))
True 
False

To know how many years are leap years in a range

import calendar
calendar.leapdays(2019,2093) 

Output- 

18 

Calendar Without using Python Calendar Module

When I was making this program for you, I took the help of this website to decide which day is the first day of the month keeping everything in check like whether the year is a leap year or not, a number of days in each month, etc.

def firstday(year,month):
    # Refer to the website above for better understanding of the program
    dict1={1:1,2:4,3:4,4:0,5:2,6:5,7:0,8:3,9:6,10:1,11:4,12:6}
    last1=int(str(year)[len(str(year))-2:])
    last=(last1//4)+1
    last=last+dict1[month]
    if isleap(year) and (month==1 or month==2) :
        last=last-1
    else:
        last=last
    if year>=1900 and year<2000:
        last+=0
    elif year>=2000 and year<3000:
        last+=6
    elif year>=1700 and year<1800:
        last+=4
    elif year>=1800 and year<=1900:
        last+=2
    last+=last1
    if last%7==1:
        return 0
    if last%7==2:
        return 1
    if last%7==3:
        return 2
    if last%7==4:
        return 3
    if last%7==5:
        return 4
    if last%7==6:
        return 5
    if last%7==0:
        return 6
    
def isleap(year):
    if (year % 4) == 0:
        if (year % 100) == 0:
            if (year % 400) == 0:
                return True
            else:
                return False
        else:
            return True
    else:
        return False
def print_calendar(year,month):
    months={1:"January",2:"Feburary",3:"March",4:"April",5:"May",6:"June",7:"July",8:"August",9:"September",10:"October",11:"November",12:"December"}
    print(year,"          ",months[month],"\n")
    days_31=[1,3,5,7,8,10,12]
    days_30=[4,6,9,11]
    print("Su  Mo  Tu  We  Th  Fr  Sa")
    day=firstday(year,month)
    
    if month in days_31:
        total_days=31
    elif (month in days_30):
        total_days=30
    else:
        if isleap(year)==True:
            total_days=29
        else:
            total_days=28
    if day!=6:       
        print(" "*(day*4-1),'01',end="")
    elif day==6:       
        print(" "*(day*4-1),'01')
    day+=1
    for i in range(2,total_days+1):
        if i<10:
            i1="0"+str(i)
        else:
            i1=i
        if day%7==0:
            print(i1,end="")
        elif day%7==1:
            print(" ",i1,end="")
        elif day%7==2: 
            print(" ",i1,end="")
        elif day%7==3:
            print(" ",i1,end="")
        elif day%7==4:
            print(" ",i1,end="")
        elif day % 7 ==5:
            print(" ",i1,end="")
        elif day %7==6:
            print(" ",i1)
        day+=1
   
print_calendar(2020,2)
2020            Feburary 

Su  Mo  Tu  We  Th  Fr  Sa
                        01
02  03  04  05  06  07  08
09  10  11  12  13  14  15
16  17  18  19  20  21  22
23  24  25  26  27  28  29

Note- This calendar can only print calendar for years between 1700 and 2100

Printing Holidays for a particular year

For this first you need to install holidays module using pip install holidays.

import holidays 

for holiday in holidays.IND(years = 2020).items(): 
    print(holiday) 
(datetime.date(2020, 1, 14), 'Makar Sankranti / Pongal') (datetime.date(2020, 1, 26), 'Republic Day') (datetime.date(2020, 8, 15), 'Independence Day') (datetime.date(2020, 10, 2), 'Gandhi Jayanti') (datetime.date(2020, 5, 1), 'Labour Day') (datetime.date(2020, 12, 25), 'Christmas')

Calendar in Python with GUI

class Application(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.grid()

        year = int(input('\nEnter Year eg. 2020\n'))
        month = int(input('\nEnter month number.\n'))
        self.create_widgets(year, month)

    def create_widgets(self, year, month):

        days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        #create labels
        for i in range(7):
            label = Label(self, text=days[i])
            label.grid(row = 0, column = i)

        weekday, numDays = monthrange(year, month)
        week = 1
        for i in range(1, numDays + 1):
            button = Button(self, text = str(i))
            button.grid(row = week, column = weekday)

            weekday += 1
            if weekday > 6:
                week += 1
                weekday = 0


root=Tk()
obj = Application(root)
root.mainloop()

python calendar

For printing a calendar for specific locale-

import calendar
cal = calendar.LocaleTextCalendar(locale='en_IN')
print(cal.formatmonth(2020, 9))

Output-

   September 2020
Mo Tu We Th Fr Sa Su
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Must Read:

Conclusion

There are many more functions in the python calendar module. We have given you a brief idea about the classes and how basic things can be done. You can try many different things on your own to understand the module better.

Try to run the programs on your side and let us know if you have any queries.

Happy Coding!

0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
x