"""
Présentation des fonctions nécessaires pour le calcul des jours fériés
"""
# datepaques(an) > Calcule la date de Pâques d'une année donnée an (=nombre entier)
# dateliste(c, sep='/') > Transforme une date chaîne 'j/m/a' en une date liste [j,m,a]
# datechaine(d, sep='/') > Transforme une date liste=[j,m,a] en une date chaîne 'jj/mm/aaaa'
# jourplus(d, n=1): > Donne la date du nième jour suivant d=[j, m, a] (n>=0)
# jourmoins(d, n=-1) > Donne la date du nième jour précédent d=[j, m, a] (n<=0)
# numjoursem(d) > Donne le numéro du jour de la semaine d'une date d=[j,m,a]
# joursem(d) > Donne le jour de semaine en texte à partir de son numéro lundi=1, mardi=2, ..., dimanche=7
# joursferiesliste(an, sd=0) > renvoie la liste des jours fériés sous forme de date-liste d=[j,m,a]
# joursferies(an, sd=0, sep='/') > renvoie la liste des jours fériés sous forme de date-chaine c=“jj/mm/aaaa”
# estferie(d,sd=0) > dit si une date d=[j,m,a] donnée est fériée France
# nbjoursouvres(d1,d2,sd=1) > Calcule le nombre de jours ouvrés entre 2 dates (format d=[j,m,a])
def datepaques(an):
"""Calcule la date de Pâques d'une année donnée an (=nombre entier)"""
a=an//100
b=an%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
jour=p+1
mois=n
return [jour, mois, an]
"""Conversion date-chaîne date-liste
Les calculs internes avec les dates se font en date-liste d=[13,10,2009] pour éviter les conversions inutiles. Mais on a besoin de fonction de conversion pour:
convertir des dates-chaînes en entrée, en dates-listes pour les calculs
convertir des dates-listes issues des calculs, en dates-chaînes pour affichage ou stockage."""
#1er cas: J'ai une date sous forme de chaîne de caractères c=“13/10/2009”, je veux la transformer en date liste: d=[13,10,2009]:
def dateliste(c, sep='/'):
"""Transforme une date chaîne 'j/m/a' en une date liste [j,m,a]"""
j, m, a = c.split(sep)
return [int(j), int(m), int(a)]
#Et le contraire: j'ai une date-liste d=[13,10,2009] et je veux la transformer en date-chaîne c=“13/10/2009”
def datechaine(d, sep='/'):
"""Transforme une date liste=[j,m,a] en une date chaîne 'jj/mm/aaaa'"""
return ("%02d" + sep + "%02d" + sep + "%0004d") % (d[0], d[1], d[2])
"""Additionner ou soustraire n jours à une date donnée
Les 2 codes suivants permettent d'additionner ou de soustraire un certain nombre de jours à une date donnée, et de trouver la nouvelle date.
Ces codes ne sont pas très subtils (calcul jour par jour) mais ils sont faciles à comprendre et sont suffisamment rapides ici."""
#Fonction pour additionner n jours (n>=0) à la date d=[j,m,a]
def jourplus(d, n=1):
"""Donne la date du nième jour suivant d=[j, m, a] (n>=0)"""
j, m, a = d
fm = [0,31,28,31,30,31,30,31,31,30,31,30,31]
if (a%4==0 and a%100!=0) or a%400==0: # bissextile?
fm[2] = 29
for i in xrange(0,n):
j += 1
if j > fm[m]:
j = 1
m += 1
if m>12:
m = 1
a += 1
return [j,m,a]
#Fonction pour soustraire n jours (n<=0) à la date d=[j,m,a]:
def jourmoins(d, n=-1):
"""Donne la date du nième jour précédent d=[j, m, a] (n<=0)"""
j, m, a = d
fm = [0,31,28,31,30,31,30,31,31,30,31,30,31]
if (a%4==0 and a%100!=0) or a%400==0: # bissextile?
fm[2] = 29
for i in xrange(0,abs(n)):
j -= 1
if j < 1:
m -= 1
if m<1:
m = 12
a -= 1
j = fm[m]
return [j,m,a]
"""Calculer le jour de semaine d'une date donnée
Le but est de dire si une date donnée d=[j,m,a] est un lundi, mardi, …
J'ai choisi l'algorithme de Maurice Kraitchik (1882–1957), et je l'ai trouvé ici: http://cosmos2000.chez.com/Vendredi13/KraitchikMethode.html."""
#La 1ère fonction donne le numéro du jour de semaine (1 pour lundi, 2 pour mardi, …, 7 pour dimanche).
def numjoursem(d):
"""Donne le numéro du jour de la semaine d'une date d=[j,m,a]
lundi=1, mardi=2, ..., dimanche=7
Algorithme de Maurice Kraitchik (1882–1957)"""
j, m, a = d
if m<3:
m += 12
a -= 1
n = (j +2*m + (3*(m+1))//5 +a + a//4 - a//100 + a//400 +2) % 7
return [6, 7, 1, 2, 3, 4, 5][n]
#La seconde fonction renvoie le jour de semaine en texte. Ex: “Mercredi” pour n=3.
def joursem(d):
"""Donne le jour de semaine en texte à partir de son numéro
lundi=1, mardi=2, ..., dimanche=7"""
return ["", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi",
"dimanche"][numjoursem(d)]
"""Calcul des jours fériés France d'une année quelconque
Ma référence pour les jours fériés France: http://fr.wikipedia.org/wiki/F%C3%AAtes_et_jours_f%C3%A9ri%C3%A9s_en_France
Les fonctions ci-dessous renvoient la liste des jours fériés France à partir d'une année quelconque.
Ces fonctions utilisent uniquement les fonctions décrites ci-dessus sur cette page
Le 2ème paramètre numérique est optionnel:
sd=0 (=defaut): tous les jours fériés.
sd=1: idem sans les samedis-dimanches.
sd=2: les jours fériés + les 2 jours fériés supplémentaires d'Alsace-Moselle.
sd=3: idem sd=2 sans les samedis-dimanches“”“
Vous pouvez adapter les jours fériés selon votre situation, région, pays, besoins et évolution de la législation.
Pour ce qui concerne le lundi de la Pentecôte, vous faites comme vous avez compris… :-D
J'ai découpé en 2 fonctions:
la 1ère renvoie la liste des dates sous forme de date-liste d=[j,m,a],
la seconde exploite cette liste pour les présenter sous forme de date-chaine c=“jj/mm/aaaa”.
L'avantage de ce découpage en 2 fonctions est qu'on peut utiliser la 1ère fonction pour d'autres calculs."""
def joursferiesliste(an, sd=0):
"""Liste des jours fériés France en date-liste de l'année an (nb entier).
sd=0 (=defaut): tous les jours fériés.
sd=1: idem sans les sammedis-dimanches.
sd=2: tous + les 2 jours fériés supplémentaires d'Alsace-Moselle.
sd=3: idem sd=2 sans les samedis-dimanches"""
F = [] # =liste des dates des jours feries en date-liste d=[j,m,a]
L = [] # =liste des libelles du jour ferie
dp = datepaques(an)
# Jour de l'an
d = [1,1,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Jour de l'an")
# Vendredi saint (pour l'Alsace-Moselle)
d = jourmoins(dp, -2)
if sd>=2:
F.append(d)
L.append(u"Vendredi saint")
# Dimanche de Paques
d = dp
if (sd==0) or (sd==2):
F.append(d)
L.append(u"Dimanche de Pâques")
# Lundi de Paques
d = jourplus(dp, +1)
F.append(d)
L.append(u"Lundi de Pâques")
# Fête du travail
d = [1,5,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Fête du travail")
# Victoire des allies 1945
d = [8,5,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Victoire des alliés 1945")
# Jeudi de l'Ascension
d = jourplus(dp, +39)
F.append(d)
L.append(u"Jeudi de l'Ascension")
# Dimanche de Pentecote
d = jourplus(dp, +49)
if (sd==0) or (sd==2):
F.append(d)
L.append(u"Dimanche de Pentecôte")
# Lundi de Pentecote
d = jourplus(d, +1)
F.append(d)
L.append(u"Lundi de Pentecôte")
# Fete Nationale
d = [14,7,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Fête Nationale")
# Assomption
d = [15,8,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Assomption")
# Toussaint
d = [1,11,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Toussaint")
# Armistice 1918
d = [11,11,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Armistice 1918")
# Jour de Noel
d = [25,12,an]
nj = numjoursem(d)
if (sd==0) or (sd==1 and nj<6) or (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Jour de Noël")
# Saint Etienne (pour l'Alsace-Moselle)
d = [26,12,an]
nj = numjoursem(d)
if (sd==2) or (sd==3 and nj<6):
F.append(d)
L.append(u"Saint Etienne")
return F, L
#Seconde fonction:
def joursferies(an, sd=0, sep='/'):
"""Liste des jours fériés France en date-chaine de l'année an (nb entier).
sd=0 (=defaut): tous les jours fériés.
sd=1: idem sans les sammedis-dimanches.
sd=2: tous + les 2 jours fériés supplémentaires d'Alsace-Moselle.
sd=3: idem sd=2 sans les samedis-dimanches"""
C = []
J = []
F, L = joursferiesliste(an, sd)
for i in xrange(0,len(F)):
C.append(datechaine(F[i])) # conversion des dates-liste en dates-chaine
J.append(joursem(F[i])) # ajout du jour de semaine
return C, J, L
#Exemple d'utilisation: tous les jours fériés (sd=0, valeur par défaut)
#F, J, L = joursferies(2009,0,'/')
#for i in xrange(0,len(F)):
# print F[i], "%10s" % (J[i]), L[i]
"""Ce qui affiche:
01/01/2009 jeudi Jour de l'an
12/04/2009 dimanche Dimanche de Pâques
13/04/2009 lundi Lundi de Pâques
01/05/2009 vendredi Fête du travail
08/05/2009 vendredi Victoire des alliés 1945
21/05/2009 jeudi Jeudi de l'Ascension
31/05/2009 dimanche Dimanche de Pentecôte
01/06/2009 lundi Lundi de Pentecôte
14/07/2009 mardi Fête Nationale
15/08/2009 samedi Assomption
01/11/2009 dimanche Toussaint
11/11/2009 mercredi Armistice 1918
25/12/2009 vendredi Jour de Noël
"""
#Et sans les samedis-dimanches (sd=1):
#F, J, L = joursferies(2009,1,'/')
#for i in xrange(0,len(F)):
# print F[i], "%10s" % (J[i]), L[i]
""" Ce qui affiche:
01/01/2009 jeudi Jour de l'an
13/04/2009 lundi Lundi de Pâques
01/05/2009 vendredi Fête du travail
08/05/2009 vendredi Victoire des alliés 1945
21/05/2009 jeudi Jeudi de l'Ascension
01/06/2009 lundi Lundi de Pentecôte
14/07/2009 mardi Fête Nationale
11/11/2009 mercredi Armistice 1918
25/12/2009 vendredi Jour de Noël
"""
"""Dit si une date est fériée France
Dit si une date d=[j,m,a] est fériée France:
si la date est fériée, renvoie son libellé (ex: “Jour de l'an”)
sinon, renvoie une chaine vide
Le paramètre sd a la même signification que précédemment, mais il ne faut pas se tromper avec la date qu'on donne: si on met un jour férié tombant un samedi avec sd=1, le verdict sera: non férié."""
def estferie(d,sd=0):
"""estferie(d,sd=0): => dit si une date d=[j,m,a] donnée est fériée France
si la date est fériée, renvoie son libellé
sinon, renvoie une chaine vide"""
j,m,a = d
F, L = joursferiesliste(a, sd)
for i in xrange(0, len(F)):
if j==F[i][0] and m==F[i][1] and a==F[i][2]:
return L[i]
return ""
#Exemple d'utilisation:
#print estferie([1,1,2009])
#Jour de l'an
#print estferie([2,1,2009])
# <= chaine vide
#print estferie([10,4,2009],sd=3)
#Vendredi saint
"""calculer le nombre de jours ouvrés France entre 2 dates
Le principe est simple: on part d'une 1ère date d1, et on teste toutes les dates une à une jusqu'à d2. On incrémente un compteur uniquement si la date testée n'est ni un samedi, ni un dimanche, ni un jour férié. On renvoie le compteur à la fin"""
def nbjoursouvres(d1,d2,sd=1):
"""Calcule le nombre de jours ouvrés entre 2 dates (format d=[j,m,a]).
d1 doit être une date antérieure à d2
d1 et d2, bornes de l'intervalle d1->d2, sont testés
sd==1: élimination des samedis, dimanches et jours fériés
sd==3: idem pour l'Alsace-Moselle
sd=0 et sd=2 n'ont pas de sens ici
"""
j1, m1, a1 = d1
j2, m2, a2 = d2
F, L = joursferiesliste(a1, sd)
n = 0
d = [j1, m1, a1]
while True:
if (d not in F) and numjoursem(d)<6:
n += 1
if d[0]==j2 and d[1]==m2 and d[2]==a2:
break
d = jourplus(d, +1)
if d[2]!=a2:
a2 = d[2]
F, L = joursferiesliste(a2, sd)
return n
#Exemple:
#print nbjoursouvres([29,4,2009],[5,5,2009],sd=1)
#4
#print nbjoursouvres([24,12,2009],[2,1,2010],sd=1)
#5
Cet article a-t-il été utile ?
C'est super !
Merci pour votre commentaire
Désolé ! Nous n'avons pas pu vous être utile
Merci pour votre commentaire
Commentaires envoyés
Nous apprécions vos efforts et nous allons corriger l'article