2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonでcalendarモジュールを使わずにカレンダーを表示する

Posted at

calendarモジュールを使わずにカレンダーを表示したかったため、datetimeモジュールを使用しました。
datetimeモジュールをどのように使ったかをまとめてみます。

動作環境

Python 3.13.5

作成したコード

import datetime
import sys
from datetime import date, timedelta


def get_last_day_of_month(year, month):
    if month == 12:
        next_month_first = datetime.datetime(year + 1, 1, 1)
    else:
        next_month_first = datetime.datetime(year, month + 1, 1)
    
    return (next_month_first - timedelta(days=1)).day


def display_calendar(year, month):
    
    print(f"     {month}{year}")
    weekday_names = ['', '', '', '', '', '', '']
    print(' '.join(weekday_names))

    first_date = date(year, month, 1)
    first_weekday = first_date.weekday()
    for _ in range(first_weekday):
        print("   ", end='')

    last_day = get_last_day_of_month(year, month)
    
    for day in range(1, last_day + 1):
        print(f"{day:2d} ", end='')
        
        if (first_weekday + day - 1) % 7 == 6:
            print()
    
    if (first_weekday + last_day - 1) % 7 != 6:
        print()


today = datetime.datetime.now()
year, month = today.year, today.month


if len(sys.argv) == 1:
    pass
    
elif len(sys.argv) == 3:
    _, option, value = sys.argv
    if option == "-m":
        try:
            month = int(value)
            
            if month < 1 or month > 12:
                print(f"{month} is neither a month number (1..12) nor a name")
                sys.exit(1)
                
        except ValueError:
            print(f"{value} is neither a month number (1..12) nor a name")
            sys.exit(1)


display_calendar(year, month)

月のラストの日を取得する

import datetime
from datetime import timedelta

def get_last_day_of_month(year, month):
    if month == 12:
        next_month_first = datetime.datetime(year + 1, 1, 1)
    else:
        next_month_first = datetime.datetime(year, month + 1, 1)
    
    return (next_month_first - timedelta(days=1)).day
  • datetimeをインポートしておく
  • timedeltaをインポートしておく
    どちらもインポートしておかないと使うことができません。
def get_last_day_of_month(year, month):

    if month == 12:
        next_month_first = datetime.datetime(year + 1, 1, 1)
    else:
        next_month_first = datetime.datetime(year, month + 1, 1)
    
    return (next_month_first - timedelta(days=1)).day

月のラストの日を取得するためには、次の月の1日からマイナス1をします。

どちらもdatetimeを使ってやっていることは同じで、yearとmonthが渡されたら新しいオブジェクトが作成されます。

  • year = 2025, month = 12が渡された場合はyearに1が足され(2026, 1, 1)がnext_month_firstに
  • year = 2025, month = 11が渡された場合はmonthに1が足され(2025, 12, 1)がnext_month_firstに

returnでnext_month_first から timedelta(days=1)で丸一日分引けば月のラストの日が取得できます。

初日の取得と表示位置を決める

    first_date = date(year, month, 1)
    first_weekday = first_date.weekday()
    for _ in range(first_weekday):
        print("   ", end='')
  1. 渡されたyearとmonthの1日をfirst_dateに代入
  2. first_dateの曜日を数字で取得(rangeは整数しか入れられない)
  3. rangeでに入っているfirst_dateの数字分for文が回され、空白が挿入されて表示位置が決まる

カレンダーに表示する日にちと改行位置を決める

    last_day = get_last_day_of_month(year, month)
    
    for day in range(1, last_day + 1):
        print(f"{day:2d} ", end='')
        
        if (first_weekday + day - 1) % 7 == 6:
            print()
    
    if (first_weekday + last_day - 1) % 7 != 6:
        print()
  1. 全ての日にちを2桁表示にして改行しないでprintする
  2. もし回ってきた日にちが7で割って余りが6だったら改行する
  3. もし月のラストの日が7で割って余りが6じゃなかったら改行する

現在の年と月を取得する

today = datetime.datetime.now()
year, month = today.year, today.month
  • datetime.datetime.now()で現在日時を取得して、年と月はそれぞれyearとmonthに代入しておく。こうすることでdisplay_calendar(year, month)が使えるようになる

sysは以下で書いたので割愛
Python標準ライブラリsysのsys.argvとsys.exit()について

まとめ

  • datetime.datetime.now()で、現在日時を取得する
  • 渡された現在日時を基にdatetime(year, month)で新しい日時を作成
  • timedeltaは来月一日から1日分マイナスするのに使った
2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?