Как получить разницу между двумя датами в формате N лет Y месяцев X дней с учетом повышающих и понижающих коэффициентов

Рейтинг: 0Ответов: 2Опубликовано: 17.01.2023

Использовал модуль dateutil.

from dateutil.parser import parse as du_parse   
from dateutil.relativedelta import relativedelta
date1 = '2021.06.07'
date2 = '2022.06.07'
d1 = du_parse(str(date1))
d2 = du_parse(str(date2))
delta = (relativedelta(d2, d1))*2
print(delta.years)
print(delta.months)
print(delta.days)

При использовании в качестве коэффициента целых чисел проблем не возникает. При использовании вещественных чисел расчет разницы между датами происходит не корректно

Ответы

▲ 1

Ну, смотрите, если вы готовое значение relativedelta на что-то умножаете, то как вы можете получить корректное число лет, месяцев и дней в принципе? Точное число лет и месяцев можно вычислить только между конкретными датами, что и делает relativedelta. Как только вы начинаете производить какие-то действия с полученными значениями, сразу становится непонятно, как их интерпретировать. Между конкретными датами понятно, сколько дней в каком месяце. А если у вас абстрактное число дней, то как его перевести в годы и месяцы - ведь вы не знаете, какие именно это годы и месяцы, сколько в них дней. Всё, что можно в таком случае сделать - это вычислить число дней между датами и умножить его на ваш коэффициент, это легко:

delta = (d2 - d1) * 0.5
print(delta.days)
# 180

Корректно перевести полученное число дней в месяцы и годы нельзя. Можно только как-то приблизительно это сделать, разделив на среднее число дней в месяце и в году.

▲ 1

Можно рассмотреть такой подход. Вычисляем дельты между двумя датами, получаем datetime.timedelta. Который умножаем на коэффициент и прибавляем к первой дате. Тем самым получаем гипотетическую дату в будущем d3 = d1 + (d2 - d1) * koeff, как если бы стаж был длиннее в коэффициент раз. После чего получаем разность между полученной (третьей) датой и первой датой. В этом случае даты получаются совершенно конкретные, с конкретными високосными и невисокосными годами, конкретным кол-вом дней в конкретных месяцах.

from dateutil.parser import parse as du_parse
from dateutil.relativedelta import relativedelta

date1 = '2021.06.07'
date2 = '2022.06.10'
d1 = du_parse(str(date1))
d2 = du_parse(str(date2))

koeff = 1.7
d3 = d1 + (d2 - d1) * koeff  # datetime.timedelta * koeff

delta = relativedelta(d2, d1)
delta_koeff = relativedelta(d3, d1)

print(f'Натурально: {delta.years} лет, {delta.months} месяцев, {delta.days} дней')
print(f'С коэфф. {koeff}: {delta_koeff.years} лет, {delta_koeff.months} месяцев, {delta_koeff.days} дней')
Натурально: 1 лет, 0 месяцев, 3 дней
С коэфф. 1.7: 1 лет, 8 месяцев, 15 дней