Use python to realize the display of the month calendar

Table of contents

1 Basic idea

2 Implementation code

3 running effect

1 Basic idea

First of all, determine the header of the calendar to be output. Here I use offset to indicate the right offset of the header. When offset is 0, the table header is from Monday to Sunday; when offset is 1, the table header is from Sunday, Monday to Saturday (translate one unit to the right). In the code, I use an offset of 1 (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday). You can modify offset if you want other headers.

The table header is determined, you need to determine the day of the week that the first day of the month corresponding to the input specific year and month should be, that is, you need to determine how many units of spaces should be output before starting the output date. The starting day of the week can be determined according to the day of the week corresponding to the first day of the reference year and month and combined with the reference year and month to calculate the distance to output the number of days corresponding to the year. When traversing the year, if the year is a leap year, add 366 days, otherwise add 365 days, and the month corresponds The number of days is determined according to the created array of days in the month, and the number of days corresponding to February in a leap year should be changed to 29 days. The standard I choose here is (January 1, 1800, corresponding to Wednesday), that is to say, the year we output cannot be less than 1800. After calculating the number of days, don't forget to take the remainder of 7, and add the offset to take the remainder, because someone may set the offset to be greater than 7.

The unit space I set is 4 spaces, the same is true for the header and the number of days below, so that we can get that the corresponding bit width of the title and the dividing line below is 28. Here I also define a function to center the string according to the bit width you input, padding characters, and the output string. According to this function, you can draw a dividing line only by inputting the bit width and padding characters.

After getting how many units of spaces to output, you can output the monthly calendar. While outputting, judge when to change the line and when to end (determined according to the array of days in the month).

2 Implementation code

dayName = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
monthName = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October",
             "November", "December"]
monthNum = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

# The offset to the right of the table header, when offset is 0, it starts from Monday, and when it is 1, it starts from Sunday
offset = 1


# Used to center the string according to the number of digits you want to output, padding characters, and the displayed string
# The default filling is a space, the default string is '', only the number of digits can be filled to output the separator line
def printCenter(len1, elem='', str1=' '):
    fill = len1 - len(elem)
    # fill1 is the number of symbols str1 to be filled on the left side of the string
    # fill2 is the number of characters on the right
    if fill % 2 == 0:
        fill1 = fill // 2
        fill2 = fill // 2
    else:
        fill1 = fill // 2
        fill2 = fill // 2 - 1
    print(str1 * fill1 + elem + str1 * fill2)


# Display the title to be displayed, including the year, month and week headers
def showTitle(year, month):
    # Display the title of the month and year
    title = monthName[month - 1] + " " + str(year)
    printCenter(28, title)

    # show dividing line
    printCenter(28, str1='-')

    # Show the header of the day of the week
    dayNameI = 7  # loop end flag
    day = (7 - offset) % 7  # Judging from which subscript to start taking the week name string
    while (dayNameI):
        print(" " + dayName[day], end='')
        day += 1
        day %= 7
        dayNameI -= 1
    print()  # new line


# Determine whether it is a leap year
def ifLeapYear(year):
    if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
        return True
    else:
        return False


def showBody(year, month):
    totalDay = 0
    # Calculates the number of days between January 1, 1800 and the specified year and month to be displayed (one month before the specified month)
    for i in range(1800, year):
        if ifLeapYear(i):
            totalDay += 366
        else:
            totalDay += 365
    for i in range(month - 1):
        totalDay += monthNum[i]

    dayStart = (totalDay + 3) % 7  # Calculate the week number corresponding to the first day of the month

    # Determine when to wrap
    # This also controls the number of blanks initially filled (output from the number, a total of 7)
    flag = (dayStart + offset) % 7

    # Before outputting the calendar, judge whether it is a leap year and modify the array monthNum of the number of days in the month
    if ifLeapYear(year):
        monthNum[1] = 29
    else:
        monthNum[1] = 28

    # space before the beginning of the output
    # If offset is 0 and the first day of the month is Tuesday, a unit of space needs to be output in front, and the unit is 4 (bit width).
    # When the first day of the month falls on Saturday (dayStart is 6), and the offset is 0, the flag is 0 (this is only one of the cases where the flag is 0), and 0-1 is -1 when outputting spaces, and the flag is  0 as a special case
    # If there is no if, when the flag is 0, there should be 6 unit spaces in front of it, and -1* wants to output characters and nothing will be output
    if flag == 0:
        print("    " * 6, end='')
    else:
        print("    " * (flag - 1), end='')

    #Output for each day of the month
    for day in range(monthNum[month - 1]):
        print("%4d" % (day + 1), end='')
        if flag % 7 == 0:
            print()
        flag += 1
    print()

# Calendar output function
def showCalendar(year, month):
    showTitle(year, month)
    showBody(year, month)


year = int(input("Please enter the year:"))
month = int(input("Please enter the month:"))
if year < 1800:
    print("Please enter a year greater than or equal to 1800")
else:
    showCalendar(year, month)

3 running effect

offset is 1, the input year is 2023, and the month is March

offset is 1, the input year is 2023, and the month is January

 

When the offset is 0, the input year is 2023, and the month is March (the header changes)

 

 

Tags: Python programming language

Posted by TCovert on Thu, 16 Mar 2023 16:38:01 +1030