Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Python で日時計算 ~ 月初とか月末とか N ヵ月前とか
# -*- coding: utf-8 -*-
from datetime import datetime
from calendar import monthrange
def add_month(_date, month_delta):
"""{month_delta} ヵ月後の同日の日時を返す
>>> add_month(datetime.datetime(2017, 1, 30, 5, 20, 15), month_delta=1)
datetime.datetime(2017, 2, 28, 23, 59, 59)
>>> add_month(datetime.datetime(2017, 1, 15, 5, 20, 15), month_delta=1)
datetime.datetime(2017, 2, 15, 5, 20, 15)
>>> add_month(datetime.datetime(2017, 1, 30, 5, 20, 15), month_delta=13)
datetime.datetime(2018, 2, 28, 23, 59, 59)
"""
year = _date.year
month = _date.month
day = _date.day
hour = _date.hour
minute = _date.minute
second = _date.second
microsecond = _date.microsecond
alt_year = year
alt_month = month + month_delta
if alt_month > 12:
month_overflow = alt_month
alt_year += month_overflow // 12
alt_month = month_overflow % 12
elif alt_month <= 0:
month_overflow = alt_month
alt_year += (month_overflow - 1) // 12
alt_month = (month_overflow - 1) % 12 + 1
try:
return datetime(alt_year, alt_month, day, hour, minute, second, microsecond)
except ValueError:
return end_of_month(datetime(alt_year, alt_month, 1, hour, minute, second, microsecond))
def sub_month(_date, month_delta):
"""{month_delta} ヵ月前の同日の日時を返す
>>> sub_month(datetime.datetime(2017, 3, 30, 5, 20, 15), month_delta=1)
datetime.datetime(2017, 2, 28, 23, 59, 59)
>>> sub_month(datetime.datetime(2017, 3, 15, 5, 20, 15), month_delta=1)
datetime.datetime(2017, 2, 15, 5, 20, 15)
>>> sub_month(datetime.datetime(2017, 3, 20, 5, 20, 15), month_delta=5)
datetime.datetime(2016, 10, 20, 5, 20, 15)
"""
return add_month(_date, -month_delta)
def start_of_month(_date):
"""その月の月初の時を返す
>>> start_of_month(datetime.datetime(2017, 3, 15))
datetime.datetime(2017, 3, 1, 0, 0)
>>> start_of_month(datetime.datetime(2017, 2, 28, 10, 10, 10))
datetime.datetime(2017, 2, 1, 0, 0)
"""
year = _date.year
month = _date.month
return datetime(year, month, 1, 0, 0, 0)
def end_of_month(_date):
"""その月の月末の日時を返す
>>> end_of_month(datetime.datetime(2017, 3, 15))
datetime.datetime(2017, 3, 31, 23, 59, 59)
>>> end_of_month(datetime.datetime(2017, 2, 28, 10, 10, 10))
datetime.datetime(2017, 2, 28, 23, 59, 59)
"""
year = _date.year
month = _date.month
end_of_month = monthrange(year, month)[1]
return datetime(year, month, end_of_month, 23, 59, 59)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment