Pythonで月末のdatetimeオブジェクトを得る

rubyActiveSupportを使うとDate型にend_of_monthというメソッドが追加され、Dateオブジェクトから月末のDateオブジェクトを得ることができます

require 'active_support/core_ext/time/calculations'
today = Date.today()

puts today
# => 2012-01-21

puts today.end_of_month
# => 2012-01-31

pythonで月末のdatetimeオブジェクトを取得する必要があったので、以下のように実装してみました

from datetime import datetime

some_day = datetime.strptime('20122', '%Y%m')

def end_of_month(date):
    import calendar
    # calendar.monthrangeは年と月を渡すと、月初と月末の日をタプルで返す
    last_day = calendar.monthrange(date.year, date.month)[1]
    date = date.replace(day=last_day)
    return date

print some_day
# => 2012-02-01 00:00:00

print end_of_month(some_day)
# => 2012-02-29 00:00:00


# 毎月の月末のオブジェクトを得る
for i in range(1, 13):
    d = datetime.strptime('2012%s' % i, '%Y%m')
    print end_of_month(d)

# => 2012-01-31 00:00:00
# => 2012-02-29 00:00:00
# => 2012-03-31 00:00:00
# => 2012-04-30 00:00:00
# => 2012-05-31 00:00:00
# => 2012-06-30 00:00:00
# => 2012-07-31 00:00:00
# => 2012-08-31 00:00:00
# => 2012-09-30 00:00:00
# => 2012-10-31 00:00:00
# => 2012-11-30 00:00:00
# => 2012-12-31 00:00:00