APSQL

Le calcul de la date de pâques

Lors de la manipulation des données de type date il est fréquent d'avoir besoin de tenir des jours fériés. Bien entendu cette liste diffère d'un pays à l'autre, et même en France cette liste est légèrement différente pour les régions les plus à l'est. Toutefois il est possible de diviser ces jours fériés en 2 catégories : ceux qui possèdent des dates fixes (1er janvier, 1er mai, 8 mai, 14 juillet, 15 août, 1er novembre, 11 novembre et 25 décembre) et ceux qui possèdent des dates variables (Pâques et le lundi de Pâques, le jeudi de l'ascension, la pentecôte et son lundi au statut bizarre). Heureusement toutes sont définies par rapport à Pâques. La connaissance de la date de pâques permet de définir la date du jeudi de la l'ascension (40 jours après Pâques en comptant le jour de Pâques) et celle du dimanche de Pentecôte (50 jours après Pâques).

Le calcul exact de la date de Pâques est donc le début à toute construction. Pour réaliser une fonction Transact SQL qui réalise ce calcul, il est possible de se baser sur l'algorithme de Oudin ( http://fr.wikipedia.org/wiki/Calcul_de_la_date_de_P%C3%A2ques#Algorithme_de_Oudin) . Cet algorithme remis au format Transact SQL donne les éléments suivants :

create function dateDePaques(@annee int) returns date as
BEGIN
  DECLARE @G int, @C int,@C_4 int;
  DECLARE @E int,@H int, @K int;
  DECLARE @P int,@Q int, @I int;
  DECLARE @B int,@J1 int, @J2 int;
  DECLARE @R int;
  DECLARE @jourDePaque date;
  set @G=@annee%19;
  set @C=@annee/100;
  set @C_4=@C/4;
  set @E=(8*@c+13)/25;
  set @H=(19*@g+ @C-@C_4-@E+15)%30;
  IF (@H=29) set @H=@H-1;
  ELSE IF (@H=28 AND @G>10) set @H=@H-1;
  set @K=@H/28;
  set @P=29/(@H+1);
  set @Q=(21-@G)/11;
  set @I=(@K*@P*@Q-1)*@K+@H;
  set @B=@annee/4+@annee;
  set @J1=@B+@I+2+@C_4-@C;
  set @J2=@J1%7;
  set @R=28+@I-@J2;
  set @jourDePaque='01/03/'+convert(char(4),@annee);
  set @jourDePaque=dateadd(dd,@r-1,@jourDePaque);
  return @jourDePaque;
END;			
			

Cette fonction très basique nécessiste en paramètre le numéro de l'année et retourne la date du jours de Pâques pour cette année passée en paramètre.

A partir de cette fonction il est relativement facile de batir une fonction qui permet de savoir si le jour passé en paramètre est férié ou non. La fonction retourne 0 si le jour n'est pas férié et 1 sinon.

Dans cet exemple seul les jours fériés présent au niveau national sont présents les jours plus spécifiques à certaines régions ne sont pas intégrés.

/*
* Fonction qui établi si le jour passé en paramètre est férie
* Base de calcul pour la france
* 1er janvier
* 1er mai
* 8 mai
* 14 juillet
* 15 aout
* 1er novembre
* 11 novembre
* 25 décembre
* Pâques et Lundi de Pâques
* Jeudi de l'ascension
* Pentecôte et Lundi de Pentecôte
*/
create function jourFerie(@jour date) returns tinyint as
begin
  declare @mois tinyint;
  declare @numeroJour tinyint;
  declare @ferie tinyint =0; --Pas férié par défaut
  declare @paques date;
  declare @ascension date;
  declare @pentecote date;
  --Est un jour ferie fixe?
  set @mois=datepart(mm,@jour);
  set @numeroJour=datepart(dd, @jour);
  if (@mois=1 AND @numeroJour=1) set @ferie=1; --1er janvier
  if (@mois=5 AND (@numeroJour=1 OR @numeroJour=8)) set @ferie=1; -- 1er ou 8 mai
  if (@mois=7 AND @numeroJour=14) set @ferie=1; -- 14 juillet
  if (@mois=8 AND @numeroJour=15) set @ferie=1; -- 15 aout
  if (@mois=11 AND (@numeroJour=1 OR @numeroJour=11)) set @ferie=1; -- 1er ou 11 novembre
  if (@mois=12 AND @numeroJour=25) set @ferie=1; -- 25 décembre
  -- Jour ferie variable?
  set @paques=dbo.dateDePaques(datepart(yy, @jour));
  set @ascension=dateadd(dd,39,@paques);
  set @pentecote=dateadd(dd,49,@paques);
  if (@jour=@paques or @jour=dateadd(dd,1,@paques)) set @ferie=1;
  if (@jour=@ascension) set @ferie=1;
  if (@jour=@pentecote or @jour=dateadd(dd,1,@pentecote)) set @ferie=1;
  return @ferie;
end;
			

Ce type de fonction va être utile dès que des calculs de dates vont devoir être effectués. Ces fonctions peuvent également être utilisées pour s'assurer de la validité d'une date.

Plus de fonctions pour manipluer les dates: