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='')
- 渡されたyearとmonthの1日をfirst_dateに代入
- first_dateの曜日を数字で取得(rangeは整数しか入れられない)
- 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()
- 全ての日にちを2桁表示にして改行しないでprintする
- もし回ってきた日にちが7で割って余りが6だったら改行する
- もし月のラストの日が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日分マイナスするのに使った