Deprecated: Array and string offset access syntax with curly braces is deprecated in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/init.php on line 563
date_de_paques [Les recettes Python de Tyrtamos]

Outils pour utilisateurs

Outils du site


date_de_paques

Ceci est une ancienne révision du document !



Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/parser/handler.php on line 1458

Warning: preg_match(): Compilation failed: invalid range in character class at offset 3565 in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/parser/lexer.php on line 118
A PCRE internal error occured. This might be caused by a faulty plugin

====== Calcul de la date de Pâques et des jours fériés (France) ====== (refonte complète de la page le 13/10/2009) ===== Calcul de la date de Pâques ===== La date de Pâques est assez complexe à calculer et encore plus à comprendre. Mais elle est importante pour calculer les jours fériés qui y sont liés. Les différentes méthodes sont ici: http://users.chariot.net.au/~gmarts/eastalg.htm J'ai choisi de programmer la méthode Hodges: http://users.chariot.net.au/~gmarts/eastalg.htm#EasterHodges J'ai vérifié ensuite avec toutes les dates ici: http://www.dioceserimouski.com/ch/paquesdates.html Ce calcul n'est valable que pour le calendrier grégorien avec des dates comprises entre 1583 et 4100 (ce qui devrait suffire pour les jours fériés :-D). Codage: <code python> 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] # Exemple d'utilisation: print paques(2008) # affiche [23, 3, 2008] </code> L'année voulue est toujours donnée en année complète (type 2008) et pas en raccourcis (type 08). Il ensuite facile de calculer les dates des jours fériés France avec une fonction qui ajoute et retranche les dates: Jeudi de l'ascension = Pâques +39 Lundi de Pentecôte = Pâques + 50 Etc... ===== Présentation des fonctions nécessaires pour le calcul des jours fériés ===== ==== 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]: <code python> 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)] </code> 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" <code python> 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]) </code> Dans les 2 cas, on peut préciser le séparateur qui est '/' par défaut. Avec cela, on peut convertir "13/10/2009" ou "13-10-2009" ou "13:10:2009" ou avec n'importe quel autre séparateur. ==== 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]: <code python> 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] </code> Fonction pour soustraire n jours (n<=0) à la date d=[j,m,a]: <code python> 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] </code> ==== 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). La seconde fonction renvoie le jour de semaine en texte. Ex: "Mercredi" pour n=3. <code python> 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] 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)] </code> Voilà. On a toutes les fonctions nécessaires pour calculer les jours fériés! ===== 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. Pour la seconde fonction, on peut préciser le séparateur à utiliser pour stocker la date sous forme de date-chaine ('/' par défaut) Première fonction <code python> 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 </code> Seconde fonction: <code python> 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 </code> Exemple d'utilisation: tous les jours fériés (sd=0, valeur par défaut) <code python> F, J, L = joursferies(2009,0,'/') for i in xrange(0,len(F)): print F[i], "%10s" % (J[i]), L[i] </code> Ce qui affiche: <code> 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 </code> Et sans les samedis-dimanches (sd=1): <code python> F, J, L = joursferies(2009,1,'/') for i in xrange(0,len(F)): print F[i], "%10s" % (J[i]), L[i] </code> Ce qui affiche: <code> 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 </code> ===== 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é. <code python> 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 "" </code> Exemple d'utilisation: <code> 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 </code> ===== 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 <code python> 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 </code> Exemple: <code> print nbjoursouvres([29,4,2009],[5,5,2009],sd=1) 4 print nbjoursouvres([24,12,2009],[2,1,2010],sd=1) 5 </code> <html> <head> <style type="text/css"> <!-- body {background-image:url(fondcorps.jpg);} --> </style> </head> <body> </body> </html>

date_de_paques.1255429383.txt.gz · Dernière modification: 2009/10/13 12:23 par tyrtamos

Outils de la page