web-dev-qa-db-fra.com

Dernier jour ouvrable précédent en Python

Je dois soustraire jours ouvrables de la date du jour. 

J'ai actuellement du code qui doit toujours être exécuté le dernier jour ouvrable. Donc, cela peut être aujourd'hui si nous sommes lundi à vendredi, mais si c'est samedi ou dimanche, alors je dois le régler au vendredi avant le week-end. J'ai actuellement quelques jolis clunky codes pour le faire:

 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

Y a-t-il un meilleur moyen? 

Puis-je dire à timedelta de travailler les jours de semaine plutôt que les jours civils, par exemple? 

56
Thomas Browne

Utilisez des pandas!

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)

Depuis aujourd'hui, le jeudi 26 septembre, vous obtiendrez une sortie de:

datetime.datetime(2013, 9, 20, 14, 8, 4, 89761)
96
Kyle Hannon

Il semble y avoir plusieurs options si vous êtes ouvert à l’installation de bibliothèques supplémentaires.

Cet article décrit une façon de définir les journées de travail avec dateutil .

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

BusinessHours vous permet de définir de manière personnalisée votre liste de vacances, etc., afin de définir votre heure de travail (et par extension, le nombre de jours ouvrables).

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

13
Alison R.

DISCLAMER: Je suis l'auteur ...

J'ai écrit un package qui fait exactement cela, des calculs de dates de travail. Vous pouvez utiliser des spécifications de semaine et des jours fériés personnalisés.

Lorsque je travaillais avec des données financières, j’avais ce problème précis et je n’ai trouvé aucune des solutions disponibles particulièrement facile. J’en ai donc écrit une.

J'espère que cela est utile pour d'autres personnes.

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

9
antoniobotelho

Peut-être que ce code pourrait aider:

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

L'idée est que les lundis, vous devez revenir 3 jours, les dimanches 2 et un autre jour.

La déclaration (lastBusDay.weekday() + 6) % 7 refond simplement le lundi de 0 à 6.

Je ne sais vraiment pas si cela sera meilleur en termes de performances.

6
TMC

timeboard package le fait.

Supposons que votre date est le 4 septembre 2017. Bien que ce soit un lundi, c'était un jour férié aux États-Unis (la fête du travail). Donc, le dernier jour ouvrable était le vendredi 1er septembre.

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

Au Royaume-Uni, le 4 septembre 2017 était le jour ouvrable normal; le dernier jour ouvrable était donc lui-même.

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

AVERTISSEMENT: Je suis l'auteur de Timeboard.

4
Maxim Mamaev

Si vous voulez sauter les jours fériés américains ainsi que les week-ends, cela a fonctionné pour moi (avec des pandas 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

Pour convertir en un objet date Python, j'ai fait ceci:

result.to_pydatetime().date()
3
lakenen

Cela donnera un générateur de jours ouvrables, bien sûr sans vacances, stop est un objet datetime.datetime. Si vous avez besoin de vacances, argumentez simplement avec la liste des vacances et vérifiez avec 'IFology' ;-)

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

Plus tard, vous pouvez les compter comme

workdays = workingdays(datetime.datetime(2015, 8, 8))
len(list(workdays))
2
mastier

Pourquoi n'essaies-tu pas quelque chose comme:

lastBusDay = datetime.datetime.today()
if datetime.date.weekday(lastBusDay) not in range(0,5):
    lastBusDay = 5
0
ValentinS
 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
TheMan