python-dateutil подсчет рабочих часов

Сегодня был задан интересный для меня вопрос о подсчете рабочего времени в минутах.
Я написал ответ основанный на использовании библиотеки python-dateutil

from datetime import datetime
from dateutil.rrule import *
from dateutil.parser import parse


def worktime_count(start: datetime, end: datetime, unit=MINUTELY):
    return len(
        [
            *rrule(
                unit,
                start,
                until=end,
                byweekday=range(0, 5),
                byhour=range(9, 18),
                wkst=MO
            )
        ]
    )


print(
    worktime_count(
        parse('2022-05-13 17:50:00'),
        parse('2022-05-16 09:10:00')
    )
)
# 21
print(
    worktime_count(
        parse('2022-05-13 17:50:00'),
        parse('2022-05-13 18:00:00')
    )
)
# 10
# Поэтому просто -1 к результату не катит

На мой взгляд ответ должен быть 20 (думаю Вы со мной согласитесь).
Посему мой ответ я удалил

Если сделать частоту генерации точек времени посекундной и потом длину списка // 60,
то ответ будет корректным.

from datetime import datetime
from dateutil.rrule import *
from dateutil.parser import parse


def worktime_count(start: datetime, end: datetime, unit=SECONDLY):
    return len(
        [
            *rrule(
                unit,
                start,
                until=end,
                byweekday=range(0, 5),
                byhour=range(9, 18),
                wkst=MO
            )
        ]
    ) // 60


print(
    worktime_count(
        parse('2022-05-13 17:50:00'),
        parse('2022-05-16 09:10:00')
    )
)
# 20

print(
    worktime_count(
        parse('2022-05-13 17:50:00'),
        parse('2022-05-13 18:00:00')
    )
)
# 10

Может быть есть у кого мысли как добиться правильного результата при поминутной частоте?

на всякий случай ссылка на доку


Ответы (1 шт):

Автор решения: Namerek

@Сергей, спасибо, натолкнули на мысль.

Задача свелась к тому, чтобы не забирать последний элемент, если он находится в диапазоне рабочего времени. Для этого перед применением параметра конечной даты уменьшаем ее на минуту

from datetime import datetime
from dateutil.rrule import *
from dateutil.parser import parse
from dateutil.relativedelta import relativedelta

def worktime_count(start: datetime, end: datetime, unit=MINUTELY):
    return len(
        [
            *rrule(
                unit,
                start,
                until=end - relativedelta(minutes=1),
                byweekday=range(0, 5),
                byhour=range(9, 18),
                wkst=MO
            )
        ]
    )
print(
    worktime_count(
        parse('2022-05-13 17:50:00'),
        parse('2022-05-16 09:10:00')
    )
)
# 20
print(
    worktime_count(
        parse('2022-05-13 17:50:00'),
        parse('2022-05-13 18:00:00')
    )
)
# 10
→ Ссылка