Python: Jours fériés français
Voici une classe que j'ai développé afin de gérer efficacement les jours fériés français.
Elle pourra être utilisée ultérieurement dans différentes applications.
Voici le code:
from enum import IntEnum
from datetime import datetime, date
from dateutil.easter import easter, EASTER_WESTERN
from dateutil.relativedelta import relativedelta
import json
from collections import namedtuple
import serpy
class Mois(IntEnum):
JANVIER = 1
FEVRIER = 2
MARS = 3
AVRIL = 4
MAI = 5
JUIN = 6
JUILLET = 7
AOUT = 8
SEPTEMBRE = 9
OCTOBRE = 10
NOVEMBRE = 11
DECEMBRE = 12
class JoursFeries(object):
def __init__(self, annee: int = datetime.now().year):
self.CURRENT_YEAR = int(annee)
@property
def CURRENT_YEAR(self) -> int:
return self._annee
@CURRENT_YEAR.setter
def CURRENT_YEAR(self, value: int) -> None:
self._annee = value
@property
def JOUR_DE_L_AN(self) -> date:
return date(self.CURRENT_YEAR, Mois.JANVIER, 1)
@property
def PAQUES(self) -> date:
return easter(self.CURRENT_YEAR, method=EASTER_WESTERN)
@property
def LUNDI_DE_PAQUES(self) -> date:
return self.PAQUES + relativedelta(days=1)
@property
def FETE_DU_TRAVAIL(self) -> date:
return date(self.CURRENT_YEAR, Mois.MAI, 1)
@property
def VICTOIRE_1945(self) -> date:
return date(self.CURRENT_YEAR, Mois.MAI, 8)
@property
def ASCENSION(self) -> date:
return self.PAQUES + relativedelta(days=39)
@property
def PENTECOTE(self) -> date:
return self.PAQUES + relativedelta(days=49)
@property
def LUNDI_DE_PENTECOTE(self) -> date:
return self.PENTECOTE + relativedelta(days=1)
@property
def FETE_NATIONALE(self) -> date:
return date(self.CURRENT_YEAR, Mois.JUILLET, 14)
@property
def ASSOMPTION(self) -> date:
return date(self.CURRENT_YEAR, Mois.AOUT, 15)
@property
def TOUSSAINT(self) -> date:
return date(self.CURRENT_YEAR, Mois.NOVEMBRE, 1)
@property
def ARMISTICE_1918(self) -> date:
return date(self.CURRENT_YEAR, Mois.NOVEMBRE, 11)
@property
def NOEL(self) -> date:
return date(self.CURRENT_YEAR, Mois.DECEMBRE, 25)
@property
def proprietes(self) -> list:
return list(self.dumps().keys())
def to_list(self) -> list:
return [getattr(self, x) for x in self.dumps().keys()]
def __str__(self) -> str:
return '\n'.join([f'{x:<20s}: {getattr(self, x)}' for x in self.dumps().keys()])
def __repr__(self) ->str:
return json.dumps(self.dumps(), indent=4, ensure_ascii=False)
def dumps(self) -> dict:
return JoursFeriesSerialize(self).data
def to_namedtuple(self) -> namedtuple:
return namedtuple('JourFeries', self.dumps().keys())(**self.dumps())
class JoursFeriesSerialize(serpy.Serializer):
JOUR_DE_L_AN = serpy.StrField()
PAQUES = serpy.StrField()
LUNDI_DE_PAQUES = serpy.StrField()
FETE_DU_TRAVAIL = serpy.StrField()
VICTOIRE_1945 = serpy.StrField()
ASCENSION = serpy.StrField()
PENTECOTE = serpy.StrField()
LUNDI_DE_PENTECOTE = serpy.StrField()
FETE_NATIONALE = serpy.StrField()
ASSOMPTION = serpy.StrField()
TOUSSAINT = serpy.StrField()
ARMISTICE_1918 = serpy.StrField()
NOEL = serpy.StrField()
La classe Mois énumère tous les mois de l'année grâce au package enum.IntEnum.
La classe JoursFeriesSerialize permet de sérialiser les données de la classe JoursFeries grâce au package serpy.
Pour finir, la classe JoursFeries qui permet de générer tous les jours fériés de l'année en cours ou de celle passée en paramètre au constructeur de la classe.
Le jour férié correspondant à Pâques est récupéré grâce au package dateutil.easter.easter et tous les jours fériés ayant un rapport avec Pâques sont générés grâce au package dateutil.relativedelta.relativedelta.
Pour l'utiliser, rien de plus simple:
>>> jf = JoursFeries()
>>> jf
{
"JOUR_DE_L_AN": "2022-01-01",
"PAQUES": "2022-04-17",
"LUNDI_DE_PAQUES": "2022-04-18",
"FETE_DU_TRAVAIL": "2022-05-01",
"VICTOIRE_1945": "2022-05-08",
"ASCENSION": "2022-05-26",
"PENTECOTE": "2022-06-05",
"LUNDI_DE_PENTECOTE": "2022-06-06",
"FETE_NATIONALE": "2022-07-14",
"ASSOMPTION": "2022-08-15",
"TOUSSAINT": "2022-11-01",
"ARMISTICE_1918": "2022-11-11",
"NOEL": "2022-12-25"
}
Sans paramètre, la classe retourne tous les jours fériés de l'année en cours.
La méthode __repr__ permet d'afficher les jours fériés au format json (str).
Avec l'année passée en paramètre:
>>> jf = JoursFeries(2024)
>>> jf
{
"JOUR_DE_L_AN": "2024-01-01",
"PAQUES": "2024-03-31",
"LUNDI_DE_PAQUES": "2024-04-01",
"FETE_DU_TRAVAIL": "2024-05-01",
"VICTOIRE_1945": "2024-05-08",
"ASCENSION": "2024-05-09",
"PENTECOTE": "2024-05-19",
"LUNDI_DE_PENTECOTE": "2024-05-20",
"FETE_NATIONALE": "2024-07-14",
"ASSOMPTION": "2024-08-15",
"TOUSSAINT": "2024-11-01",
"ARMISTICE_1918": "2024-11-11",
"NOEL": "2024-12-25"
}
La méthode to_list retourne une liste contenant tous les jours fériés au format datetime.date
>>> jf.to_list()
[datetime.date(2022, 1, 1),
datetime.date(2022, 4, 17),
datetime.date(2022, 4, 18),
datetime.date(2022, 5, 1),
datetime.date(2022, 5, 8),
datetime.date(2022, 5, 26),
datetime.date(2022, 6, 5),
datetime.date(2022, 6, 6),
datetime.date(2022, 7, 14),
datetime.date(2022, 8, 15),
datetime.date(2022, 11, 1),
datetime.date(2022, 11, 11),
datetime.date(2022, 12, 25)]
Un print de l'objet:
>>> print(jf)
JOUR_DE_L_AN : 2022-01-01
PAQUES : 2022-04-17
LUNDI_DE_PAQUES : 2022-04-18
FETE_DU_TRAVAIL : 2022-05-01
VICTOIRE_1945 : 2022-05-08
ASCENSION : 2022-05-26
PENTECOTE : 2022-06-05
LUNDI_DE_PENTECOTE : 2022-06-06
FETE_NATIONALE : 2022-07-14
ASSOMPTION : 2022-08-15
TOUSSAINT : 2022-11-01
ARMISTICE_1918 : 2022-11-11
NOEL : 2022-12-25
La méthode dumps retourne une représentation json (dict)
>>> jf.dumps()
{'JOUR_DE_L_AN': '2022-01-01',
'PAQUES': '2022-04-17',
'LUNDI_DE_PAQUES': '2022-04-18',
'FETE_DU_TRAVAIL': '2022-05-01',
'VICTOIRE_1945': '2022-05-08',
'ASCENSION': '2022-05-26',
'PENTECOTE': '2022-06-05',
'LUNDI_DE_PENTECOTE': '2022-06-06',
'FETE_NATIONALE': '2022-07-14',
'ASSOMPTION': '2022-08-15',
'TOUSSAINT': '2022-11-01',
'ARMISTICE_1918': '2022-11-11',
'NOEL': '2022-12-25'}
La méthode to_namedtuple retourne un objet collections.namedtuple
>>> jf.to_namedtuple()
JourFeries(JOUR_DE_L_AN='2022-01-01', PAQUES='2022-04-17', LUNDI_DE_PAQUES='2022-04-18', FETE_DU_TRAVAIL='2022-05-01', VICTOIRE_1945='2022-05-08', ASCENSION='2022-05-26', PENTECOTE='2022-06-05', LUNDI_DE_PENTECOTE='2022-06-06', FETE_NATIONALE='2022-07-14', ASSOMPTION='2022-08-15', TOUSSAINT='2022-11-01', ARMISTICE_1918='2022-11-11', NOEL='2022-12-25')
Pour afficher le jour férié correspondant à Pâques
>>> jf.PAQUES
datetime.date(2022, 4, 17)
>>> jf.PAQUES.year
2022
>>> jf.PAQUES.day
17
>>> jf.PAQUES.month
4
>>> jf.PAQUES.isocalendar()
(2022, 15, 7) # le 7ème jour de la semaine 15 de l'année 2022
>>> jf.PAQUES.isoformat()
2022-04-17
>>> jf.PAQUES.timetuple()
time.struct_time(tm_year=2022, tm_mon=4, tm_mday=17, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=107, tm_isdst=-1)
Tous les jours fériés disposent des mêmes fonctions.
Comme les jours fériés sont au format datetime.date, toutes les méthodes de l'objet datetime.date sont également accessibles.
La méthode proprietes affiche la liste des noms de tous les jours fériés
>>> jf.proprietes
['JOUR_DE_L_AN',
'PAQUES',
'LUNDI_DE_PAQUES',
'FETE_DU_TRAVAIL',
'VICTOIRE_1945',
'ASCENSION',
'PENTECOTE',
'LUNDI_DE_PENTECOTE',
'FETE_NATIONALE',
'ASSOMPTION',
'TOUSSAINT',
'ARMISTICE_1918',
'NOEL']
Ce qui permet de faire ceci
>>> for nom in jf.proprietes: ... print(f"{nom:<20} {getattr(JoursFeries(dtstart.year), nom).strftime('%a %d %B %Y')}")
JOUR_DE_L_AN Sat 01 Jan 2022 PAQUES Sun 17 Apr 2022 LUNDI_DE_PAQUES Mon 18 Apr 2022 FETE_DU_TRAVAIL Sun 01 May 2022 VICTOIRE_1945 Sun 08 May 2022 ASCENSION Thu 26 May 2022 PENTECOTE Sun 05 Jun 2022 LUNDI_DE_PENTECOTE Mon 06 Jun 2022 FETE_NATIONALE Thu 14 Jul 2022 ASSOMPTION Mon 15 Aug 2022 TOUSSAINT Tue 01 Nov 2022 ARMISTICE_1918 Fri 11 Nov 2022 NOEL Sun 25 Dec 2022
Vraiment super pratique.
Ajouter un commentaire