102 votes

Jour ouvré précédent le plus récent en Python

Je dois soustraire des jours ouvrés de la date actuelle.

J'ai actuellement du code qui doit toujours être en cours d'exécution le jour ouvré le plus récent. Ainsi, ce peut être aujourd'hui si nous sommes du lundi au vendredi, mais si c'est samedi ou dimanche alors je dois le ramener au vendredi précédent le week-end. J'ai actuellement un code assez lourd pour faire cela :

 lastBusDay = datetime.datetime.today()
 if datetime.date.weekday(lastBusDay) == 5:      #si c'est samedi
     lastBusDay = lastBusDay - datetime.timedelta(days = 1) #alors faire de vendredi
 elif datetime.date.weekday(lastBusDay) == 6:      #si c'est dimanche
     lastBusDay = lastBusDay - datetime.timedelta(days = 2); #alors faire de vendredi

Est-ce qu'il y a une meilleure façon?

Puis-je dire à timedelta de travailler en jours ouvrés plutôt qu'en jours calendaires par exemple?

192voto

Kyle Hannon Points 199

Utilisez pandas!

import datetime
# BDay est un jour ouvré, pas un anniversaire...
from pandas.tseries.offsets import BDay

today = datetime.datetime.today()
print(today - BDay(4))

Comme aujourd'hui est jeudi, le 26 septembre, cela vous donnera une sortie de :

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

28voto

lakenen Points 848

Si vous voulez éviter les jours fériés aux États-Unis ainsi que les week-ends, cela a fonctionné pour moi (en utilisant 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()

18voto

TMC Points 71

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 doivent être ajustés de 3 jours en arrière, les dimanches de 2 jours, et de 1 jour pour tous les autres jours.

L'instruction (lastBusDay.weekday() + 6) % 7 permet simplement de basculer le lundi de 0 à 6.

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

13voto

Alison R. Points 2674

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

Ce post décrit une façon de définir les jours ouvrables avec dateutil:

import datetime
from dateutil import rrule
alpha=datetime.date(2004, 01, 01) # change to accept input
omega=datetime.date(2004, 02, 01) # change to accept input
dates=rrule.rruleset() # create an rrule.rruleset instance
dates.rrule(rrule.rrule(rrule.FREQ_DAILY, dtstart=alpha, until=omega))
             # this set is INCLUSIVE of alpha and omega
dates.exrule(rrule.rrule(rrule.FREQ_DAILY,
                        byweekday=(rrule.SA, rrule.SU),
                        dtstart=alpha))
# here's where we exclude the weekend dates
print len(list(dates)) # there's probably a faster way to handle this

BusinessHours vous permet de définir sur mesure votre liste de jours fériés, etc., pour définir quand sont vos heures de travail (et par extension vos jours de travail).

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

11voto

antoniobotelho Points 113

Avertissement : Je suis l'auteur...

J'ai écrit une extension qui fait exactement cela, des calculs de dates commerciales. Vous pouvez utiliser une spécification de semaine personnalisée et des jours fériés.

J'ai rencontré ce même problème en travaillant avec des données financières et je n'ai pas trouvé les solutions disponibles particulièrement faciles, alors j'en ai écrit une.

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

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X