Разницу между датами в рабочих днях можно вычислить, используя библиотеку datetime
и модуль calendar
(или специализированную библиотеку, например, pandas
или workdays
):
import datetime
import calendar
def working_days_difference(start_date, end_date):
"""Вычисляет количество рабочих дней между двумя датами."""
total_days = (end_date - start_date).days + 1 # Включаем конечную дату
working_days = 0
for i in range(total_days):
current_date = start_date + datetime.timedelta(days=i)
if calendar.weekday(current_date.year, current_date.month, current_date.day) < 5: # 0-4: пн-пт
working_days += 1
return working_days
# Пример использования:
start = datetime.date(2023, 10, 26)
end = datetime.date(2023, 11, 10)
diff = working_days_difference(start, end)
print(f"Количество рабочих дней: {diff}")
Этот код перебирает все дни между датами и проверяет, является ли день рабочим (понедельник-пятница).
Альтернативный подход (с `pandas`):
import pandas as pd
def working_days_difference_pandas(start_date, end_date):
"""Вычисляет количество рабочих дней между двумя датами, используя pandas."""
dates = pd.date_range(start_date, end_date, freq='B') # 'B' означает только бизнес-дни
return len(dates)
# Пример использования:
start = pd.to_datetime('2023-10-26').date() # Преобразуем в datetime.date
end = pd.to_datetime('2023-11-10').date() # Преобразуем в datetime.date
diff = working_days_difference_pandas(start, end)
print(f"Количество рабочих дней: {diff}")
Использование `pandas` обычно быстрее и позволяет более гибко учитывать праздничные дни (путем передачи списка праздников в `pd.date_range`).
Для вычисления разницы между датами в рабочих днях на Python можно использовать несколько подходов. Наиболее распространенные и эффективные решения включают использование модуля datetime
и библиотеки holidays
. Вот несколько вариантов с объяснениями и примерами кода:
1. Использование datetime
и простого цикла:
Этот подход предполагает итерацию по дням между двумя датами и проверку, является ли каждый день рабочим (не выходным).
import datetime
def calculate_working_days(start_date, end_date):
"""
Вычисляет количество рабочих дней между двумя датами (исключая выходные - суббота и воскресенье).
"""
if start_date > end_date:
start_date, end_date = end_date, start_date # Swap if start_date is after end_date
total_days = (end_date - start_date).days + 1
working_days = 0
for i in range(total_days):
current_date = start_date + datetime.timedelta(days=i)
if current_date.weekday() < 5: # 0-4: Monday-Friday
working_days += 1
return working_days
# Пример использования
start_date = datetime.date(2023, 10, 26)
end_date = datetime.date(2023, 11, 10)
working_days = calculate_working_days(start_date, end_date)
print(f"Количество рабочих дней между {start_date} и {end_date}: {working_days}")
Плюсы: Простота реализации.
Минусы: Не учитывает праздничные дни; неэффективно для больших интервалов дат.
2. Использование datetime
и списочных включений (List Comprehension):
Более компактная версия предыдущего подхода.
import datetime
def calculate_working_days_comprehension(start_date, end_date):
if start_date > end_date:
start_date, end_date = end_date, start_date
dates = [start_date + datetime.timedelta(days=i) for i in range((end_date - start_date).days + 1)]
working_days = sum(1 for date in dates if date.weekday() < 5)
return working_days
# Пример использования
start_date = datetime.date(2023, 10, 26)
end_date = datetime.date(2023, 11, 10)
working_days = calculate_working_days_comprehension(start_date, end_date)
print(f"Количество рабочих дней между {start_date} и {end_date}: {working_days}")
Плюсы: Более компактный код.
Минусы: Не учитывает праздничные дни; создает временный список, что может быть неэффективно для больших интервалов.
3. Использование библиотеки holidays
для учета праздников:
Библиотека holidays
позволяет получить список праздников для конкретной страны или региона. Это позволяет точно вычислить рабочие дни, исключая как выходные, так и праздники.
import datetime
import holidays
def calculate_business_days(start_date, end_date, country='RU'): # Default country is Russia
"""
Вычисляет количество рабочих дней между двумя датами, исключая выходные и праздники.
"""
if start_date > end_date:
start_date, end_date = end_date, start_date
country_holidays = holidays.CountryHoliday(country, years=start_date.year)
total_days = (end_date - start_date).days + 1
business_days = 0
for i in range(total_days):
current_date = start_date + datetime.timedelta(days=i)
if current_date.weekday() < 5 and current_date not in country_holidays:
business_days += 1
return business_days
# Пример использования
start_date = datetime.date(2023, 10, 26)
end_date = datetime.date(2023, 11, 10)
business_days = calculate_business_days(start_date, end_date, country='RU')
print(f"Количество рабочих дней между {start_date} и {end_date}: {business_days}")
# Чтобы установить holidays: pip install holidays
Плюсы: Учитывает праздничные дни, что дает более точный результат.
Минусы: Требуется установка дополнительной библиотеки (holidays
); может быть медленнее для очень больших диапазонов дат.
4. Использование `numpy` и `busdaycalendar`:
Для очень больших диапазонов дат, `numpy` с его `busdaycalendar` может быть более производительным.
import datetime
import numpy as np
def calculate_business_days_numpy(start_date, end_date, holidays=[]):
"""
Вычисляет количество рабочих дней между двумя датами, исключая выходные и список праздников.
Использует numpy.busday_count.
"""
if start_date > end_date:
start_date, end_date = end_date, start_date
bus_days = np.busday_count(start_date, end_date, holidays=holidays) # end_date is exclusive
return bus_days
# Пример использования
start_date = datetime.date(2023, 10, 26)
end_date = datetime.date(2023, 11, 10)
# Add some sample holidays for demonstration
holidays_list = [datetime.date(2023, 11, 3), datetime.date(2023, 11, 6)] # Replace with actual holiday dates
business_days = calculate_business_days_numpy(start_date, end_date, holidays=holidays_list)
print(f"Количество рабочих дней между {start_date} и {end_date}: {business_days}")
# Чтобы установить numpy: pip install numpy
Плюсы: Высокая производительность, особенно для больших диапазонов дат. Легко интегрировать список праздников.
Минусы: Требует установки дополнительной библиотеки (numpy
); немного менее читаемый код.
Выбор подходящего метода:
holidays
(третий метод). Убедитесь, что выбранная страна поддерживается библиотекой.numpy
(четвертый метод).