
program Paques;

{ Date de Pâques par l'algorithme d'Oudin pour une année donnée du calendrier grégorien. }

uses
{$IFDEF unix}
  clocale,
{$ENDIF}
  SysUtils;

{
  Date de Pâques pour les années postérieures à 1582, par l'algorithme d'Oudin.
  L'algorithme d'Oudin permet de déterminer la date de Pâques pour n'importe quelle année du calendrier grégorien, c'est-à-dire pour n'importe quelle année postérieure à 1582.
  Lorsque le résultat de l'algorithme est un nombre inférieur ou égal à 31, ce nombre correspond à un jour de mars. Lorsque le nombre est supérieur à 31, c'est que Pâques tombe en avril. Par exemple, si le nombre est égal à 32, c'est que Pâques tombe le 1er avril (le 32 mars en quelque sorte).
}
function NombreOudin(const AAnnee: word): word;
var
  G, C, C4, E, H, K, P, Q, I, B, J1, J2: word;
begin
  G := AAnnee mod 19;                     WriteLn('G = ', G);
  C := AAnnee div 100;                    WriteLn('C = ', C);
  C4 := C div 4;                          WriteLn('C4 = ', C4);
  E := (8 * C + 13) div 25;               WriteLn('E = ', E);
  H := (19 * G + C - C4 - E + 15) mod 30; WriteLn('H = ', H);
  K := H div 28;                          WriteLn('K = ', K);
  P := 29 div (H + 1);                    WriteLn('P = ', P);
  Q := (21 - G) div 11;                   WriteLn('Q = ', Q);
  I := (K * P * Q - 1) * K + H;           WriteLn('I = ', I);
  B := (AAnnee div 4) + AAnnee;           WriteLn('B = ', B);
  J1 := B + I + 2 + C4 - C;               WriteLn('J1 = ', J1);
  J2 := J1 mod 7;                         WriteLn('J2 = ', J2);
  result := 28 + I - J2;                  WriteLn('result = ', result);
end;

function DatePaques(const AAnnee: word): TDate;
var
  LNombreOudin: word;
  LAvril: boolean;
begin
  LNombreOudin := NombreOudin(AAnnee);
  LAvril := LNombreOudin > 31;
  result := EncodeDate(AAnnee, Ord(LAvril) + 3, LNombreOudin - 31 * Ord(LAvril));
end;

var
  LDate: TDate;
  
begin
  LDate := DatePaques(CurrentYear);
  WriteLn('Pâques');
  WriteLn(FormatDateTime('dddd d mmmm yyyy', LDate));      // dimanche 1 avril 2018
  WriteLn('Cendres');
  WriteLn(FormatDateTime('dddd d mmmm yyyy', LDate - 46)); // mercredi 14 février 2018
end.
