Самый последний предыдущий рабочий день в Python - PullRequest
61 голосов
/ 08 февраля 2010

Мне нужно вычесть рабочих дней из текущей даты.

В настоящее время у меня есть код, который всегда должен быть запущен в самый последний рабочий день. Так что это может быть сегодня, если мы будем с понедельника по пятницу, но если это суббота или воскресенье, то мне нужно перенести его на пятницу до выходных. У меня сейчас есть какой-то красивый неуклюжий код для этого:

 lastBusDay = datetime.datetime.today()
 if datetime.date.weekday(lastBusDay) == 5:      #if it's Saturday
     lastBusDay = lastBusDay - datetime.timedelta(days = 1) #then make it Friday
 elif datetime.date.weekday(lastBusDay) == 6:      #if it's Sunday
     lastBusDay = lastBusDay - datetime.timedelta(days = 2); #then make it Friday

Есть ли лучший способ?

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

Ответы [ 9 ]

105 голосов
/ 26 сентября 2013

Используйте панд!

import pandas as pd
# BDay is business day, not birthday...
from pandas.tseries.offsets import BDay

# pd.datetime is an alias for datetime.datetime
today = pd.datetime.today()
print today - BDay(4)

Поскольку сегодня четверг, 26 сентября, вы получите:

datetime.datetime(2013, 9, 20, 14, 8, 4, 89761)
13 голосов
/ 08 февраля 2010

Кажется, есть несколько вариантов, если вы открыты для установки дополнительных библиотек.

В этом посте описан способ определения рабочих дней с помощью dateutil .

http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-09/3758.html

BusinessHours позволяет вам настраивать свой список праздничных дней и т. Д., Чтобы определить, когда ваши рабочие часы (и по дополнительным рабочим дням) равны.

http://pypi.python.org/pypi/BusinessHours/

9 голосов
/ 22 июня 2014

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я автор ...

Я написал пакет, который делает именно это, расчеты деловых дат. Вы можете использовать пользовательские спецификации недели и праздников.

У меня была именно эта проблема при работе с финансовыми данными, и я не нашел ни одного из доступных решений особенно простым, поэтому я написал одно.

Надеюсь, что это полезно для других людей.

https://pypi.python.org/pypi/business_calendar/

7 голосов
/ 01 февраля 2012

Может быть, этот код может помочь:

lastBusDay = datetime.datetime.today()
shift = datetime.timedelta(max(1,(lastBusDay.weekday() + 6) % 7 - 3))
lastBusDay = lastBusDay - shift

Идея состоит в том, что по понедельникам вам нужно возвращаться на 3 дня, на воскресенье 2 и на 1 в любой другой день.

Выражение (lastBusDay.weekday() + 6) % 7 просто пересчитывает понедельник с 0 до 6.

На самом деле не знаю, будет ли это лучше с точки зрения производительности.

4 голосов
/ 12 марта 2018

timeboard пакет делает это.

Предположим, ваша дата 04 сентября 2017 года. Несмотря на то, что в понедельник в США был выходной (День труда) Итак, последний рабочий день был пятница, 1 сентября.

>>> import timeboard.calendars.US as US
>>> clnd = US.Weekly8x5()
>>> clnd('04 Sep 2017').rollback().to_timestamp().date()
datetime.date(2017, 9, 1)

В Великобритании 04 сентября 2017 года был обычный рабочий день, поэтому самый последний рабочий день был сам по себе.

>>> import timeboard.calendars.UK as UK
>>> clnd = UK.Weekly8x5()
>>> clnd('04 Sep 2017').rollback().to_timestamp().date()
datetime.date(2017, 9, 4)

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я являюсь автором табло.

3 голосов
/ 26 июля 2018

Если вы хотите пропустить праздники США, а также выходные, это сработало для меня (используя панд 0.23.3):

import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar
from pandas.tseries.offsets import CustomBusinessDay
US_BUSINESS_DAY = CustomBusinessDay(calendar=USFederalHolidayCalendar())
july_5 = pd.datetime(2018, 7, 5)
result = july_5 - 2 * US_BUSINESS_DAY # 2018-7-2

Чтобы преобразовать объект даты в python, я сделал это:

result.to_pydatetime().date()
2 голосов
/ 23 мая 2015

Это даст генератор рабочих дней, конечно, без выходных, остановка - объект datetime.datetime. Если вам нужны праздники, просто добавьте дополнительный аргумент в список праздников и проверьте с помощью 'IFology'; -)

def workingdays(stop, start=datetime.date.today()):
    while start != stop:
        if start.weekday() < 5:
            yield start
        start += datetime.timedelta(1)

Позже вы можете считать их как

workdays = workingdays(datetime.datetime(2015, 8, 8))
len(list(workdays))
0 голосов
/ 30 апреля 2014
 def getNthBusinessDay(startDate, businessDaysInBetween):
    currentDate = startDate
    daysToAdd = businessDaysInBetween
    while daysToAdd > 0:
        currentDate += relativedelta(days=1)
        day = currentDate.weekday()
        if day < 5:
            daysToAdd -= 1

    return currentDate 
0 голосов
/ 19 августа 2013

Почему бы вам не попробовать что-то вроде:

lastBusDay = datetime.datetime.today()
if datetime.date.weekday(lastBusDay) not in range(0,5):
    lastBusDay = 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...