Skip to content

Instantly share code, notes, and snippets.

@SebCorbin
Last active March 13, 2020 09:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save SebCorbin/756c46bf1c20ebf5746cad3a871f28dd to your computer and use it in GitHub Desktop.
Save SebCorbin/756c46bf1c20ebf5746cad3a871f28dd to your computer and use it in GitHub Desktop.
"""
Générateur de jours ouvrés français en python
"""
def easter_date(year):
"""
Calcule la date du jour de Pâques d'une année donnée
Voir https://github.com/dateutil/dateutil/blob/master/dateutil/easter.py
:return: datetime
"""
a = year // 100
b = year % 100
c = (3 * (a + 25)) // 4
d = (3 * (a + 25)) % 4
e = (8 * (a + 11)) // 25
f = (5 * a + b) % 19
g = (19 * f + c - e) % 30
h = (f + 11 * g) // 319
j = (60 * (5 - d) + b) // 4
k = (60 * (5 - d) + b) % 4
m = (2 * j - k - g + h) % 7
n = (g - h + m + 114) // 31
p = (g - h + m + 114) % 31
day = p + 1
month = n
return datetime(year, month, day)
def is_holiday(the_date):
"""
Vérifie si la date donnée est un jour férié
:param the_date: datetime
:return: bool
"""
year = the_date.year
easter = easter_date(year)
days = [
datetime(year, 1, 1), # Premier de l'an
easter + timedelta(days=1), # Lundi de Pâques
datetime(year, 5, 1), # Fête du Travail
datetime(year, 5, 8), # Victoire de 1945
easter + timedelta(days=39), # Ascension
easter + timedelta(days=49), # Pentecôte
datetime(year, 7, 14), # Fête Nationale
datetime(year, 8, 15), # Assomption
datetime(year, 11, 1), # Toussaint
datetime(year, 11, 11), # Armistice 1918
datetime(year, 12, 25), # Noël
]
return the_date in days
def business_days(date_from, date_to):
"""
Générateur retournant les jours ouvrés dans la période [date_from:date_to]
:param date_from: Date de début de la période
:param date_to: Date de fin de la période
:return: Générateur
"""
while date_from <= date_to:
# Un jour est ouvré s'il n'est ni férié, ni samedi, ni dimanche
if not is_holiday(date_from) and date_from.isoweekday() not in [6, 7]:
yield date_from
date_from += timedelta(days=1)
@MaximeWeyl
Copy link

Il y a une erreur, pour la pentecôte il faut faire easter + 50 (pour avoir le lundi) au lieu de +49 (qui donne toujours un dimanche).

@SebCorbin
Copy link
Author

Il y a une erreur, pour la pentecôte il faut faire easter + 50 (pour avoir le lundi) au lieu de +49 (qui donne toujours un dimanche).

La Pentecôte est toujours un dimanche, cf https://fr.wikipedia.org/wiki/Pentec%C3%B4te, le lundi de Pentecôte est bien le jour d'après donc +50. Il est parfois un jour travaillé, c'est donc pour ça qu'il n'est pas férié et ne fait pas partie de la liste cf le commentaire Pentecôte != Lundi de pentecôte.

@MaximeWeyl
Copy link

C'est clair, au temps pour moi. Dans mon cas le calcul dépendait du fait de considérer le lundi comme férié.

@SebCorbin
Copy link
Author

SebCorbin commented Mar 13, 2020

Update : Je vous invite à jeter un oeil à https://pypi.org/project/workalendar/ également

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment