Была у меня одна простенькая задачка - определять по дате рождения пенсионер человек или нет.
До недавнего времени отлично работало следующее решение: из текущей даты вычитаем 60 и 55 лет и получаем минимальную дату рождения мужчины и женщины, для которых наступил пенсионный возраст. После этого сравниваем эту дату с датой рождения конкретного человека и определяем пенсионер он или нет. Ниже приведён код данного решения (только обсуждаемая часть):
import datetime
now_date = datetime.date.today() # Текущая дата (без времени)
cur_year = now_date.year # Год текущий
men_retirement_date = now_date.replace(year = cur_year - 60)
women_retirement_date = now_date.replace(year = cur_year - 55)
...
for people in list:
if isMale:
isPensioner = brs_date < men_retirement_date
else:
isPensioner = brs_date < women_retirement_date
Решение было всем хорошее, кроме одного момента - при вычитании годов (для определения даты выхода на пенсию) не учитывалось, что в високосные годы в феврале на 1 день больше, поэтому при запуске 29 февраля программка вылетела с ошибкой преобразования даты.
Теперь же, после принятия новой пенсионной реформы, появился переходный период и пришлось писать отдельную функцию для того же функционала (посмотреть код).
import datetime
def isPensioner(isMale, dtBirth):
"""Вычисляет является человек пенсионером или нет.
Параметры:
isMale - пол: для мужчин - True, для женщин - False
dtBirth - дата рождения"""
is_pensioner = False # пенсионер?
retirement_age = 55
addhalfyear = False
retirement_date = dtBirth
birth_year = dtBirth.year
birth_month = dtBirth.month
birth_day = dtBirth.day
if isMale:
if birth_year <= 1958:
retirement_age = 60
elif birth_year == 1959:
retirement_age = 60
addhalfyear = True
elif birth_year == 1960:
retirement_age = 61
addhalfyear = True
elif birth_year == 1961:
retirement_age = 63
elif birth_year == 1962:
retirement_age = 64
else:
retirement_age = 65
else: # Female
if birth_year <= 1963:
retirement_age = 55
elif birth_year == 1964:
retirement_age = 55
addhalfyear = True
elif birth_year == 1965:
retirement_age = 56
addhalfyear = True
elif birth_year == 1966:
retirement_age = 58
elif birth_year == 1967:
retirement_age = 59
else:
retirement_age = 60
# прибавим к дате рождения пенсионный возраст
if birth_day > 28:
retirement_date = retirement_date.replace(day = 28)
retirement_date = retirement_date.replace(year = birth_year + retirement_age)
if addhalfyear:
if birth_month > 6:
retirement_date = retirement_date.replace(year = birth_year + retirement_age + 1)
retirement_date = retirement_date.replace(month = birth_month + 6 - 12)
else:
retirement_date = retirement_date.replace(month = birth_month + 6)
if birth_day > 28:
nday = 28
while nday < birth_day:
nday += 1
try:
retirement_date = retirement_date.replace(day = nday)
except ValueError:
pass
is_pensioner = now_date > retirement_date
return is_pensioner
for people in list:
if isMale:
isPensioner = isPensioner(True, brs_date)
else:
isPensioner = isPensioner(False, brs_date)
Учитывая необходимость добавления полугодовых интервалов, в ней также была реализована проверка корректности вновь формируемых дат: перед сдвигом если день больше 28 принудительно устанавливаем 28 число (т.к. такой день есть в любом месяце), далее производим необходимые манипуляции с датой (добавляем года и, при необходимости, месяцы), а потом пробуем поднять дату до необходимой, перехватывая возможные исключения.
PS Для прибавления 6 месяцев к указанной дате на StackOverflow предложили использовать отдельную библиотеку dateutil, но мне показалось, что в данном случае это было бы избыточно, да и лишнюю зависимость "тащить" не хотелось. Ниже предложенное там решение:
from datetime import date
from dateutil.relativedelta import relativedelta
six_months = date.today() + relativedelta(months=+6)
Напомню, что предварительно библиотеку надо установить: pip install python-dateutil