Python月の日数・週数を取得する方法【calendar活用完全ガイド】
Pythonで指定した月の日数や週数を取得する方法を、calendarモジュールとdatetimeモジュールを使用して詳しく解説します。うるう年の考慮やISO週番号の取得方法も含めて学びましょう。
月の日数を取得する基本方法
calendarモジュールを使用
import calendar
# 指定した年月の日数を取得
year = 2024
month = 2
# monthrangeで月の情報を取得
weekday, days = calendar.monthrange(year, month)
print(f"{year}年{month}月の日数: {days}日") # 29日(うるう年)
print(f"1日の曜日: {weekday} (0=月曜日)")
# 複数の月の日数を一括取得
months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for m in months:
_, days = calendar.monthrange(year, m)
print(f"{m}月: {days}日")
datetimeモジュールを使用
from datetime import date, timedelta
def get_days_in_month(year, month):
"""指定した年月の日数を取得"""
# 次の月の1日から1日を引く
if month == 12:
next_month = date(year + 1, 1, 1)
else:
next_month = date(year, month + 1, 1)
last_day = next_month - timedelta(days=1)
return last_day.day
# 使用例
year = 2024
month = 2
days = get_days_in_month(year, month)
print(f"{year}年{month}月の日数: {days}日")
月末日を直接取得
from datetime import date, datetime
import calendar
def get_last_day_of_month(year, month):
"""月の最終日を取得"""
_, last_day = calendar.monthrange(year, month)
return date(year, month, last_day)
def get_month_info(year, month):
"""月の詳細情報を取得"""
first_day = date(year, month, 1)
last_day = get_last_day_of_month(year, month)
return {
'year': year,
'month': month,
'first_day': first_day,
'last_day': last_day,
'days_count': last_day.day,
'first_weekday': first_day.weekday(),
'last_weekday': last_day.weekday()
}
# 使用例
info = get_month_info(2024, 2)
print(f"月情報: {info}")
月の週数を取得する方法
calendarモジュールで週数計算
import calendar
def get_weeks_in_month(year, month):
"""月の週数を取得"""
month_calendar = calendar.monthcalendar(year, month)
return len(month_calendar)
def get_detailed_weeks_info(year, month):
"""月の週情報を詳細に取得"""
month_calendar = calendar.monthcalendar(year, month)
weeks_info = {
'total_weeks': len(month_calendar),
'weeks': [],
'partial_weeks': 0,
'full_weeks': 0
}
for i, week in enumerate(month_calendar):
week_days = [day for day in week if day != 0] # 0以外の日付
is_partial = len(week_days) < 7
week_info = {
'week_number': i + 1,
'days': week,
'actual_days': week_days,
'days_count': len(week_days),
'is_partial': is_partial
}
weeks_info['weeks'].append(week_info)
if is_partial:
weeks_info['partial_weeks'] += 1
else:
weeks_info['full_weeks'] += 1
return weeks_info
# 使用例
year = 2024
month = 2
weeks_count = get_weeks_in_month(year, month)
print(f"{year}年{month}月の週数: {weeks_count}週")
detailed_info = get_detailed_weeks_info(year, month)
print(f"完全週: {detailed_info['full_weeks']}週")
print(f"部分週: {detailed_info['partial_weeks']}週")
ISO週番号での週数計算
from datetime import date, timedelta
def get_iso_weeks_in_month(year, month):
"""ISO週番号を使用した月の週数計算"""
# 月の最初と最後の日
first_day = date(year, month, 1)
if month == 12:
last_day = date(year + 1, 1, 1) - timedelta(days=1)
else:
last_day = date(year, month + 1, 1) - timedelta(days=1)
# ISO週番号を取得
first_week = first_day.isocalendar()[1]
last_week = last_day.isocalendar()[1]
# 年をまたぐ場合の考慮
if last_week < first_week: # 12月末から1月初旬の場合
weeks_in_year = date(year, 12, 28).isocalendar()[1]
total_weeks = (weeks_in_year - first_week + 1) + last_week
else:
total_weeks = last_week - first_week + 1
return {
'total_iso_weeks': total_weeks,
'first_iso_week': first_week,
'last_iso_week': last_week,
'first_day': first_day,
'last_day': last_day
}
# 使用例
iso_info = get_iso_weeks_in_month(2024, 1)
print(f"ISO週数情報: {iso_info}")
実用的な週計算関数
営業週の計算
import calendar
from datetime import date, timedelta
def get_business_weeks_info(year, month):
"""営業週の情報を取得"""
month_calendar = calendar.monthcalendar(year, month)
business_info = {
'total_weeks': len(month_calendar),
'business_days_per_week': [],
'total_business_days': 0
}
for week in month_calendar:
business_days = 0
for day_num in week:
if day_num != 0: # 有効な日付
day_date = date(year, month, day_num)
if day_date.weekday() < 5: # 月〜金
business_days += 1
business_info['business_days_per_week'].append(business_days)
business_info['total_business_days'] += business_days
return business_info
# 使用例
business_info = get_business_weeks_info(2024, 1)
print(f"営業日情報: {business_info}")
週ごとの詳細分析
import calendar
from datetime import date
def analyze_month_by_weeks(year, month):
"""月を週ごとに詳細分析"""
month_calendar = calendar.monthcalendar(year, month)
weekday_names = ['月', '火', '水', '木', '金', '土', '日']
analysis = {
'month': f"{year}年{month}月",
'total_weeks': len(month_calendar),
'weeks_detail': []
}
for week_num, week in enumerate(month_calendar, 1):
week_detail = {
'week_number': week_num,
'dates': [],
'business_days': 0,
'weekend_days': 0,
'total_days': 0
}
for day_index, day in enumerate(week):
if day != 0:
day_date = date(year, month, day)
weekday_name = weekday_names[day_index]
day_info = {
'date': day,
'weekday': weekday_name,
'is_business_day': day_index < 5,
'is_weekend': day_index >= 5
}
week_detail['dates'].append(day_info)
week_detail['total_days'] += 1
if day_index < 5:
week_detail['business_days'] += 1
else:
week_detail['weekend_days'] += 1
analysis['weeks_detail'].append(week_detail)
return analysis
# 使用例
analysis = analyze_month_by_weeks(2024, 1)
print(f"=== {analysis['month']} 週別分析 ===")
for week in analysis['weeks_detail']:
print(f"第{week['week_number']}週: {week['total_days']}日 "
f"(営業日: {week['business_days']}日, 週末: {week['weekend_days']}日)")
複数月の比較分析
年間の月別日数・週数比較
import calendar
def compare_months_in_year(year):
"""年間の月別日数・週数を比較"""
month_names = ['', '1月', '2月', '3月', '4月', '5月', '6月',
'7月', '8月', '9月', '10月', '11月', '12月']
comparison = {
'year': year,
'months': [],
'total_days': 0,
'total_weeks': 0
}
for month in range(1, 13):
_, days = calendar.monthrange(year, month)
weeks = len(calendar.monthcalendar(year, month))
month_data = {
'month': month,
'month_name': month_names[month],
'days': days,
'weeks': weeks,
'is_leap_year': calendar.isleap(year) and month == 2
}
comparison['months'].append(month_data)
comparison['total_days'] += days
comparison['total_weeks'] += weeks
return comparison
# 使用例
year_comparison = compare_months_in_year(2024)
print(f"=== {year_comparison['year']}年 月別比較 ===")
print(f"年間総日数: {year_comparison['total_days']}日")
print(f"年間総週数: {year_comparison['total_weeks']}週")
print("\n月別詳細:")
for month_data in year_comparison['months']:
leap_note = " (うるう年)" if month_data['is_leap_year'] else ""
print(f"{month_data['month_name']}: {month_data['days']}日, {month_data['weeks']}週{leap_note}")
四半期ごとの集計
import calendar
def quarterly_analysis(year):
"""四半期ごとの日数・週数分析"""
quarters = {
'Q1': [1, 2, 3],
'Q2': [4, 5, 6],
'Q3': [7, 8, 9],
'Q4': [10, 11, 12]
}
quarterly_data = {}
for quarter, months in quarters.items():
total_days = 0
total_weeks = 0
total_business_days = 0
for month in months:
_, days = calendar.monthrange(year, month)
weeks = len(calendar.monthcalendar(year, month))
# 営業日の計算
business_days = 0
month_calendar = calendar.monthcalendar(year, month)
for week in month_calendar:
for day_index, day in enumerate(week):
if day != 0 and day_index < 5: # 月〜金
business_days += 1
total_days += days
total_weeks += weeks
total_business_days += business_days
quarterly_data[quarter] = {
'total_days': total_days,
'total_weeks': total_weeks,
'business_days': total_business_days,
'weekend_days': total_days - total_business_days
}
return quarterly_data
# 使用例
quarterly_data = quarterly_analysis(2024)
print("=== 2024年 四半期別分析 ===")
for quarter, data in quarterly_data.items():
print(f"{quarter}: {data['total_days']}日, {data['total_weeks']}週 "
f"(営業日: {data['business_days']}日)")
特殊な計算パターン
月の第N週の日数計算
import calendar
def get_nth_week_days(year, month, week_number):
"""月の第N週の日数を取得"""
month_calendar = calendar.monthcalendar(year, month)
if week_number > len(month_calendar) or week_number < 1:
return None
week = month_calendar[week_number - 1]
actual_days = [day for day in week if day != 0]
return {
'week_number': week_number,
'days': week,
'actual_days': actual_days,
'days_count': len(actual_days),
'is_full_week': len(actual_days) == 7
}
# 使用例
nth_week = get_nth_week_days(2024, 1, 1)
print(f"第1週の情報: {nth_week}")
月またぎ週の計算
import calendar
from datetime import date, timedelta
def get_cross_month_weeks(year, month):
"""月をまたぐ週の情報を取得"""
# 当月のカレンダー
current_month = calendar.monthcalendar(year, month)
# 前月と次月の最後/最初の週を取得
prev_month = month - 1 if month > 1 else 12
prev_year = year if month > 1 else year - 1
next_month = month + 1 if month < 12 else 1
next_year = year if month < 12 else year + 1
prev_month_cal = calendar.monthcalendar(prev_year, prev_month)
next_month_cal = calendar.monthcalendar(next_year, next_month)
result = {
'first_week_incomplete': current_month[0][0] == 0,
'last_week_incomplete': current_month[-1][6] == 0,
'cross_month_weeks': []
}
# 最初の週が不完全な場合
if result['first_week_incomplete']:
prev_week_days = [day for day in prev_month_cal[-1] if day != 0]
current_week_days = [day for day in current_month[0] if day != 0]
result['cross_month_weeks'].append({
'type': 'first_week',
'prev_month_days': prev_week_days,
'current_month_days': current_week_days,
'total_days': len(prev_week_days) + len(current_week_days)
})
# 最後の週が不完全な場合
if result['last_week_incomplete']:
current_week_days = [day for day in current_month[-1] if day != 0]
next_week_days = [day for day in next_month_cal[0] if day != 0]
result['cross_month_weeks'].append({
'type': 'last_week',
'current_month_days': current_week_days,
'next_month_days': next_week_days,
'total_days': len(current_week_days) + len(next_week_days)
})
return result
# 使用例
cross_weeks = get_cross_month_weeks(2024, 1)
print(f"月またぎ週の情報: {cross_weeks}")
統計情報の生成
月の統計サマリー
import calendar
from datetime import date
def generate_month_statistics(year, month):
"""月の統計情報を生成"""
_, days_in_month = calendar.monthrange(year, month)
month_calendar = calendar.monthcalendar(year, month)
# 曜日ごとの日数カウント
weekday_counts = [0] * 7
weekday_names = ['月', '火', '水', '木', '金', '土', '日']
for week in month_calendar:
for day_index, day in enumerate(week):
if day != 0:
weekday_counts[day_index] += 1
# 統計情報の計算
business_days = sum(weekday_counts[:5]) # 月〜金
weekend_days = sum(weekday_counts[5:]) # 土日
statistics = {
'year': year,
'month': month,
'total_days': days_in_month,
'total_weeks': len(month_calendar),
'business_days': business_days,
'weekend_days': weekend_days,
'weekday_distribution': dict(zip(weekday_names, weekday_counts)),
'is_leap_year': calendar.isleap(year),
'month_efficiency': round(business_days / days_in_month * 100, 1)
}
return statistics
# 使用例と表示
stats = generate_month_statistics(2024, 1)
print(f"=== {stats['year']}年{stats['month']}月 統計情報 ===")
print(f"総日数: {stats['total_days']}日")
print(f"週数: {stats['total_weeks']}週")
print(f"営業日: {stats['business_days']}日")
print(f"週末: {stats['weekend_days']}日")
print(f"営業日効率: {stats['month_efficiency']}%")
print("\n曜日別分布:")
for weekday, count in stats['weekday_distribution'].items():
print(f" {weekday}曜日: {count}日")
まとめ
- 日数取得:
calendar.monthrange()で月の日数を効率的に取得 - 週数計算:
calendar.monthcalendar()で週単位の分析が可能 - 営業日計算:曜日情報を活用した実用的な計算
- 統計分析:月別、四半期別、年間の比較分析
- 特殊パターン:月またぎ週、第N週、ISO週番号の考慮
これらの方法を活用することで、カレンダーベースの様々な計算処理が効率的に実装できます。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座
