При редактировании ОП упоминается настоящая основная проблема:
"Сколько часов оплачиваемого времени отработано с даты X до даты Y?"
Я согласен, и я рассчитал бы это самым прямым и простым способом, например:
import datetime
import itertools
accrual_months_days = (1,1), (4,1), (7,1), (10,1)
def accruals(begin_date, end_date, hours_per=8):
"""Vacation accrued between begin_date and end_date included."""
cur_year = begin_date.year - 1
result = 0
for m, d in itertools.cycle(accrual_months_days):
if m == 1: cur_year += 1
d = datetime.date(cur_year, m, d)
if d < begin_date: continue
if d > end_date: return result
result += hours_per
if __name__ == '__main__': # examples
print accruals(datetime.date(2010, 1, 12), datetime.date(2010, 9, 20))
print accruals(datetime.date(2010, 4, 20), datetime.date(2012, 12, 21))
print accruals(datetime.date(2010, 12, 21), datetime.date(2012, 4, 20))
Прямая формула, конечно, была бы быстрее, но было бы сложно сделать это без ошибок - еслиничто иное, этот пример «исправить по проверке» может служить для автоматической калибровки более быстрого, проверяя, согласны ли они с большой выборкой пар дат (обязательно включите в последний все угловые случаи, такие как первый и последний дни кварталовконечно).