検索ガイド -Search Guide-

単語と単語を空白で区切ることで AND 検索になります。
例: python デコレータ ('python' と 'デコレータ' 両方を含む記事を検索します)
単語の前に '-' を付けることで NOT 検索になります。
例: python -デコレータ ('python' は含むが 'デコレータ' は含まない記事を検索します)
" (ダブルクオート) で語句を囲むことで 完全一致検索になります。
例: "python data" 実装 ('python data' と '実装' 両方を含む記事を検索します。'python data 実装' の検索とは異なります。)
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
>>
python_cookbook

Python Cookbook [Finding the Date Range for the Current Month : その月は何日まで?] 投稿一覧へ戻る

Published 2020年4月18日18:17 by mootaro23

SUPPORT UKRAINE

- Your indifference to the act of cruelty can thrive rogue nations like Russia -

Problem:
ある月の全ての日を簡単にループ処理したい。


Solution:
対象となる月の日数分のリストを用意するような必要はありません。
開始日(その月の1日)と終了日(翌月の1日)を取得し、datetime.timedelta オブジェクトを利用してその間を1日ずつループしていきます。

from datetime import datetime, date, timedelta
import calendar

def get_month_range(start_date = None):
if start_date is None:
start_date = date.today()

start_date = start_date.replace(day = 1)
_, days_in_month = calendar.monthrange(start_date.year, start_date.month)
end_date = start_date + timedelta(days = days_in_month)
return (start_date, end_date)



ここでは、対象となる月の初日を求めるために date 又は datetime オブジェクトの replace 関数を利用しています。


replace 関数は、対象が date オブジェクトであれば変換結果も date を、datetime オブジェクトであれば datetime をちゃんと返してくれます。使い勝手がいいです。


続いて、calendar.monthrange() 関数を利用して対象月の日数を取得しています。この関数は、対象月の初日の曜日と日数をタプルで返します。


最後に、取得した日数で timedelta オブジェクトを作成し加算することで最終日を取得しています。
この「最終日」は実は対象月の翌月の1日です。


ここでこのような仕様にしているのは、Python におけるスライスや範囲の扱いが「最終点は含まない」となっているため、それに合わせるためです。


作成した関数を利用すれば、対象月の初日から最終日まで簡単にループできます。

a_day = timedelta(days = 1)
first_day, last_day = get_month_range(date(2020, 2, 18))
while first_day < last_day:
print(first_day)
first_day += a_day

# 2020-02-01
# 2020-02-02
# ...
# 2020-02-28
# 2020-02-29
#
# 2020年は閏年なので 29 日までですね。



first_day, last_day = get_month_range(date(2019, 2, 3))
while first_day < last_day:
print(first_day)
first_day += a_day

# 2019-02-01
# 2019-02-02
# ...
# 2019-02-27
# 2019-02-28




もしかすると、組み込みの range() 関数と同様な動きを日付に対して行うような関数を用意できれば理想的かもしれません。


実は generator を利用することで非常に簡単に実装できます。

def date_range(start, stop, step):
while start < stop:
yield start
start += step



使い方の一例です。

for d in date_range(datetime(2020, 4, 18), datetime(2020, 5, 7), timedelta(hours = 6)):
print(d)

# 2020-04-18 00:00:00
# 2020-04-18 06:00:00
# 2020-04-18 12:00:00
# ...
# 2020-05-06 06:00:00
# 2020-05-06 12:00:00
# 2020-05-06 18:00:00