Dans tous mes développements Power BI, il y a une table temps, une dimension calendrier. Je ne vous rappelle pas l’importance de cette table dans les calculs temporels en DAX.
Générer cette table automatiquement est maintenant possible en DAX avec les fonctions CALENDAR et CALENDARAUTO(). Je vous passe également les multiples exemples que vous pourrez trouver sur Internet (blog de Chris Webb par exemple ;-)).
Le but de cet article est d’ajouter une information à notre dimension calendrier : savoir si un jour est férié ou pas. Je vous partage une fonction en M que vous n’avez plus qu’à appeler.
Disclaimer : je parle bien ici des jours fériés en FRANCE!! A vous d’adapter en fonction de votre pays.
Le plus compliqué, c’est de calculer le jour de Pâques qui tombe un peu n’importe comment. Il y a évidemment une formule :
La date de Pâques est fixée au premier dimanche après la première pleine lune qui suit le 21 mars, donc au plus tôt le 22 mars, si la pleine lune tombe le soir du 21, et au plus tard le 25 avril.
Source Wikipedia
J’avoue que j’ai honteusement pompé un algo sur un site de développement (C# je crois) et je l’ai retranscrit en M.
GetEasterDay = (annee) => let g = Number.Mod(annee,19), c = Number.IntegerDivide(annee,100), c4 = Number.IntegerDivide(c,4), e=Number.IntegerDivide((8*c+13),25), h=Number.Mod((19*g+ c-c4-e+15),30), h2 = if (h=29) then 28 else if (h=28 and g>10) then h-1 else h, k=Number.IntegerDivide(h2,28), p=Number.IntegerDivide(29,(h2+1)), q=Number.IntegerDivide((21-g),11), i=(k*p*q-1)*k+h2, b=Number.IntegerDivide(annee,4)+annee, j1=b+i+2+c4-c, j2=Number.Mod(j1,7), r=28+i-j2, jourDePaquesSTR="01/03/"&Text.From(annee), jourDePaquesDate = Date.FromText(jourDePaquesSTR), jourDePaque=Date.AddDays(jourDePaquesDate, r-1) in jourDePaque
C’est pas très académique et je suis sûr qu’il y a moyen de faire plus propre mais je recopie cette fonction telle quelle de Power BI en Power BI. L’idée est de vous le partager.
Il ne reste plus qu’à encapsuler cela dans une méthode qui traite tous les jours fériés :
(date) => let annee = Date.Year(date), jour = Date.Day(date), mois = Date.Month(date), paques = GetEasterDay(annee), paquesLundi = Date.AddDays(paques, 1), ascension=Date.AddDays(paques, 39), pentecote=Date.AddDays(paques, 49), pentecoteLundi = Date.AddDays(pentecote, 1), estFerié = if (mois=1 and jour=1) then true else if (mois=5 and jour=1) then true else if (mois=5 and jour=8) then true else if (mois=7 and jour=14) then true else if (mois=8 and jour=15) then true else if (mois=11 and jour=1) then true else if (mois=11 and jour=11) then true else if (mois=12 and jour=25) then true else if (date = paques) then true else if (date = paquesLundi) then true else if (date = ascension) then true else if (date = pentecote) then true else if (date = pentecoteLundi) then true else false in estFerié
Et voila, je vous laisse intégrer cela dans vos calendrier.
—
GetEasterDay
Bonjour,
Merci pour le boulot, ça m’a permis de découvrir Dax et M.
J’avais déjà eu a utiliser cette fonction dans excel.
Par contre j’ai une formule plus rapide pour trouver le jour de pâques:
Ici on saisi juste l’année,
let
JdeP = (my_year) =>
let
crea_date = #date(my_year,1,1),
g = Number.Mod(my_year,19),
f = Number.Mod(234-11*g,30),
c = #date(my_year,4,f),
d = Number.From(c),
e = Number.Round(d/7,0)*7-6,
JP = Date.From(e)
in
JP
in
JdeP
C’est en effet plus court donc plus rapide (mais toujours aussi abscon :)).
Merci pour le partage