мне нужна функция для расчета времени в секундах между двумя датами, за исключением выходных дней, то, что будет работать так:Время между двумя датами, кроме выходных
# friday 9 PM
start_date = datetime.datetime(2015, 9, 18, 21, 0, 0)
# monday 3 AM
end_date = datetime.datetime(2015, 9, 21, 3, 0, 0)
# should return 6 hours
time = time_between_two_dates_except_weekends(start_date, end_date)
я реализовал свою собственную функцию, которая работает, но это кажется излишне огромным и сложным. Я думаю, что это может быть проще.
import datetime
from dateutil.relativedelta import relativedelta
from dateutil.rrule import DAILY, rrule
def time_between_two_dates_except_weekends(start_date, end_date):
WEEKEND_DAYS = [5, 6]
result = datetime.timedelta()
if all([start_date.year == end_date.year, start_date.month == end_date.month, start_date.day == end_date.day]):
result += datetime.timedelta(seconds = (end_date-start_date).seconds)
return result
day_after_start_date = start_date + relativedelta(days=1)
day_after_start_date = day_after_start_date.replace(hour=0, minute=0, second=0)
day_before_end_date = end_date - relativedelta(days=1)
if start_date.weekday() not in WEEKEND_DAYS:
result += datetime.timedelta(seconds = (day_after_start_date - start_date).total_seconds())
dates_range = rrule(
DAILY,
byhour=0,
byminute=0,
bysecond=0,
dtstart=day_after_start_date,
until=day_before_end_date
)
for date in dates_range:
if date.weekday() not in WEEKEND_DAYS:
result += datetime.timedelta(seconds=24 * 60 * 60)
if end_date.weekday() not in WEEKEND_DAYS:
end_date_beginning = end_date.replace(hour=0, minute=0, second=0)
result += datetime.timedelta(seconds = (end_date - end_date_beginning).total_seconds())
return result
Есть ли способ улучшить это?
UPD. оказалось, что не только мой код сложный, но и неправильный результат в некоторых случаях (например, когда выходные дни передаются либо для начала, либо для даты окончания). Я рекомендую использовать только код из правильного ответа ниже
Пожалуйста, примите это к группе обзора кода. – Prune
Я голосую, чтобы закрыть этот вопрос не по теме, потому что он принадлежит к Code Review StackExchange. https://codereview.stackexchange.com –
Вы можете сделать свой код короче, уменьшив проверку выходных дней в конце вашего кода, добавив параметр byweekday = range (5) в ваш rrule. – avenet