Implementazioni di algoritmi/Calcolo della Pasqua

Indice del libro

Programmi di calcolo della Pasqua per il calendario gregoriano secondo il metodo di Gauss, in diversi linguaggi di programmazione.

 10 'PASQUA.BAS
 20 'Calcolo data della pasqua calendario gregoriano
 30 M$(3) = "Marzo": M$(4) = "Aprile"
 40 FOR J% = 1 TO 10: KEY J%, "": NEXT J%: KEY OFF
 60 COLOR 15,1: CLS: LOCATE 2,10: PRINT "CALCOLO DELLA DATA DELLA PASQUA NEL CALENDARIO GREGORIANO"
 70 LOCATE 12, 30: INPUT "Anno "; A%
 80 IF A% =< 1582 THEN BEEP : GOTO 60
 100 E% = A% + 3999: A# = FIX(E% * 365.25) + E% \ 400 - E% \ 100
 120 B% = A% \ 100 + 1: F% = 5 * A% \ 4 - 3 * B% \ 4 + 2
 130 B% = (11 * (A% MOD 19) + (8 * B% + 5) \ 25 + 38 - 3 * B% \ 4) MOD 30
 140 B% = 44 - B% + ((B% = 25 AND (A% MOD 19) > 10) OR B% = 24)
 150 B% = B% - 30 * (B% < 21): F% = B% + 7 - ((F% + B%) MOD 7)
 160 M% = 3 - (F% > 31): F% = F% + 31 * (F% > 31) 'mese e giorno di Pasqua
 180 LOCATE 12, 30, 0: PRINT F% M$(M%) A%
 190 LOCATE 20, 8: PRINT "Premi 'Esc' per uscire dal programma o un tasto per cambiare anno"
 200 Z$ = INKEY$: IF Z$ = "" THEN 200 ELSE ZZ$ = MID$(Z$, 2, 1): S% = ASC(Z$)
 210 IF S% = 27 THEN SYSTEM ELSE 60
var anno = new Date().getFullYear();

var a;
var b;
var c;
var Y = anno;
var d;
var e;
var M;
var N;
var giorno;
var mese;

if (Y < 2099) {
    M = 24;
    N = 5;
} else if (Y < 2199) {
    M = 24;
    N = 6;
} else if (Y < 2299) {
    M = 25;
    N = 0;
} else if (Y < 2399) {
    M = 26;
    N = 1;
} else if (Y < 2499) {
    M = 25;
    N = 1;
}

a = Y % 19;
b = Y % 4;
c = Y % 7;
d = ((19 * a) + M) % 30;
e = ((2 * b) + (4 * c) + (6 * d) + N) % 7;

if (d + e < 10) {
    giorno = d + e + 22;
    mese = 3;
} else {
    giorno = d + e - 9;
    mese = 4;
}

if (giorno == 26 && mese == 4) {
    giorno = 19;
    mese = 4;
}

if (giorno == 25 && mese == 4 && d == 28 && e == 6 && a > 10) {
    giorno = 18;
    mese = 4;
}

return [String(mese), String(giorno)].join('-');
function [day,month]=Easter(Y)

%EASTER Function for the evaluation of day of Catholic Easter
%
%
%[DAY,MONTH]=EASTER(YEAR) returns the DAY and MONTH of Catholic Easter of
%            YEAR. Note that YEAR must be lower than 2500

if (Y < 2099)

	M = 24;
	N = 5;

elseif (Y < 2199)

	M = 24;
	N = 6;


elseif (Y < 2299)

	M = 25;
	N = 0;

elseif (Y < 2399)

	M = 26;
	N = 1;

elseif(Y < 2499)

	M = 25;
	N = 1;
end
   
a = mod(Y,19);
b = mod(Y, 4);
c = mod(Y , 7);
d = mod(((19*a) + M) , 30);
e = mod(((2*b) + (4*c) + (6*d) + N) , 7);

if (d + e < 10)

	day = d+e+22;
	month = 3;

else
	day = d+e-9;
	month = 4;
end

if (day==26 && month==4)

	day = 19;
	month = 4;
end

if (day==25 && month==4 && d==28 && e==6 && a>10)

	day=18;
	month=4;
end
#include <stdio.h>

struct dataCal 
{
	int giorno;
	int mese;
	int anno;
};

struct dataCal pasqua(int anno)
{
	
	int giorno, mese;
	int a, b, c, d, e, m, n;
	struct dataCal r;

	switch(anno/100)
	{
		case 15:	// 1583 - 1599 (FALL THROUGH)
		case 16:	// 1600 - 1699
			m=22; n=2; 	break;

		case 17:	// 1700 - 1799
			m=23; n=3; break;

		case 18:	// 1800 - 1899
			m=23; n=4; break;

		case 19:	// 1900 - 1999 (FALL THROUGH)
		case 20:	// 2000 - 2099
			m=24; n=5;break;

		case 21:	// 2100 - 2199
			m=24; n=6; break;

		case 22:	// 2200 - 2299
			m=25; n=0; break;

		case 23:	// 2300 - 2399
			m=26; n=1; break;

		case 24:	// 2400 - 2499
			m=25; n=1; break;
	}
 
	a=anno%19;
	b=anno%4;
	c=anno%7;
	d=(19*a+m)%30;
	e=(2*b+4*c+6*d+n)%7;
	giorno=d+e;

	if (d+e<10)
	{
		giorno+=22;
		mese=3;
	}

	else
	{
		giorno-=9;
		mese=4;

		if ((giorno==26)||((giorno==25)&&(d==28)&&(e==6)&&(a>10)))
		{
			giorno-=7;
		}
	}

	r.giorno=giorno;
	r.mese=mese;
	r.anno=anno;
	return(r);
}

int main()
{
	int anno;
	struct dataCal r;

	for(anno=1583;anno<=2499;anno++)
	{
		r=pasqua(anno);
		printf("%02d-%02d-%d\n", r.giorno, r.mese, r.anno);	// gg-mm-aa
	}
}
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 
 public class Easter {
 	public static class YearOutOfRangeException extends Exception {
 		private static final long serialVersionUID = 5394938690797595980L;
 	}
 	
 	public final static boolean isEaster(Date date) 
 		throws YearOutOfRangeException  {
 		
 		Calendar calendar = new GregorianCalendar();
 		calendar.setTime(date);
 				
 		int year = calendar.get(Calendar.YEAR);
 		int dateYMD = year * 10000 + 
 					calendar.get(Calendar.MONTH) * 100 +  
 					calendar.get(Calendar.DAY_OF_MONTH);
 		Date easter = find(year);
 		calendar.setTime(easter);
 		int easterYMD = year * 10000 + 
 					calendar.get(Calendar.MONTH) * 100 +  
 					calendar.get(Calendar.DAY_OF_MONTH);
 		return ( easterYMD == dateYMD );
 	}
 	
 	
 	public final static Date find(int year) 
 		throws YearOutOfRangeException {
 		
 		if ( (year < 1573) || (year > 2499) ) {
 			throw new Easter.YearOutOfRangeException();
 		}
 		
 		int a = year % 19;
 		int b = year % 4;
 		int c = year % 7;
 		
 		int m = 0;
 		int n = 0;
 		
 		if ( (year >= 1583) && (year <= 1699) ) { m = 22; n = 2; }
 		if ( (year >= 1700) && (year <= 1799) ) { m = 23; n = 3; }
 		if ( (year >= 1800) && (year <= 1899) ) { m = 23; n = 4; }
 		if ( (year >= 1900) && (year <= 2099) ) { m = 24; n = 5; }
 		if ( (year >= 2100) && (year <= 2199) ) { m = 24; n = 6; }
 		if ( (year >= 2200) && (year <= 2299) ) { m = 25; n = 0; }
 		if ( (year >= 2300) && (year <= 2399) ) { m = 26; n = 1; }
 		if ( (year >= 2400) && (year <= 2499) ) { m = 25; n = 1; }
 		
 		int d = (19 * a + m) % 30;
 		int e = (2 * b + 4 * c + 6 * d + n) % 7;   
 
 		Calendar calendar = new GregorianCalendar();
 		calendar.set(Calendar.YEAR , year);
 		
 		if ( d+e < 10 ) {
 			calendar.set(Calendar.MONTH , Calendar.MARCH);
 			calendar.set(Calendar.DAY_OF_MONTH, d + e + 22);
 		} else {
 			calendar.set(Calendar.MONTH , Calendar.APRIL);
 			int day = d+e-9;
 			if ( 26 == day ) {day = 19;}
 			if ( ( 25 == day ) && ( 28 == d) && ( e == 6 ) && ( a > 10 ) ) { day = 18; }
 			calendar.set(Calendar.DAY_OF_MONTH, day);
 		}
 		
 		return calendar.getTime();
 	}
 }

Questa versione è reversibile, cioè permette indifferentemente di calcolare il giorno della Pasqua dato l'anno, oppure gli anni in cui la Pasqua è caduta in un certo giorno.

 pasqua(Anno,Mese,Giorno):-
    numero(Anno,1600,2599),
    pasqua_ground(Anno,Mese,Giorno).
 
 pasqua_ground(Anno,aprile,19):- pasqua1(Anno,aprile,26,_,_,_),!.
 pasqua_ground(Anno,aprile,18):- pasqua1(Anno,aprile,25,28,6,A),
    A>10,!.
 pasqua_ground(Anno,Mese,Giorno):- pasqua1(Anno,Mese,Giorno,_,_,_).
 
 pasqua1(Anno,marzo,G,D,E,A):-
    gauss(Anno,D,E,A),
    D+E<10,
    G is (D + E + 22).
 pasqua1(Anno,aprile,G,D,E,A):-
    gauss(Anno,D,E,A),
    G is (D + E  9).
 
 gauss(Anno,D,E,A):-
    A is Anno mod 19,
    B is Anno mod 4,
    C is Anno mod 7,
    S is fix(Anno/100),
    mn(S,M,N),
    D is (19*A+M) mod 30,
    E is (2*B+4*C+6*D+N) mod 7.
 
 numero(_,Min,Max):- Min>Max,!,fail.
 numero(X,X,_).
 numero(X,Min,Max):- Min1 is Min+1, numero(X,Min1,Max). 
 
 mn(16,22,2).  
 mn(17,23,3).  
 mn(18,23,4).
 mn(19,24,5).
 mn(20,24,5).
 mn(21,24,6).
 mn(22,25,0).
 mn(23,26,1).
 mn(24,25,1).
 unit UPasqua;
 
 interface
 
 uses SysUtils;
 
 function Pasqua(anno : Word) : TDateTime;
 
 implementation
 
 function Pasqua(anno : Word) : TDateTime;
 var
   M, N : Word;
   a, b, c, d, e : Word;
   mese, giorno : Word;
 begin
   if not (anno in [1583..2499]) then begin
      MessageBox(0, PChar('L' + #39 + 'anno deve essere maggiore di 1582 ed inferiore di 2500'),
                 'Errore', MB_OK or MB_ICONERROR);
      Result := Now;
      Exit;
   end;
 
   case anno of
     1583..1699 : begin M := 22; N := 2; end;
     1700..1799 : begin M := 23; N := 3; end;
     1800..1899 : begin M := 23; N := 4; end;
     1900..2099 : begin M := 24; N := 5; end;
     2100..2199 : begin M := 24; N := 6; end;
     2200..2299 : begin M := 25; N := 0; end;
     2300..2399 : begin M := 26; N := 1; end;
     2400..2499 : begin M := 25; N := 1; end;
     else begin M := 0; N := 0; end;
   end;
 
   a := anno mod 19;
   b := anno mod 4;
   c := anno mod 7;
 
   d := (19 * a + M) mod 30;
   e := (2 * b + 4 * c + 6 * d + N) mod 7;
 
   if d + e < 10 then begin
      mese := 3;
      giorno := d + e + 22;
   end
   else begin
      mese := 4;
      giorno := d + e - 9;
   end;
 
   if ((giorno = 26) and (mese = 4)) or
      ((giorno = 25) and (mese = 4) and (d = 28) and (e = 6) and (a > 10)) then
      Dec(giorno, 7);
 
   Result := EncodeDate(anno, mese, giorno);
 end;
 
 end.
CREATE FUNCTION [dbo].[CalcolaPasqua]
(
	@Anno INT
)
RETURNS DATETIME
AS
BEGIN
DECLARE @a DECIMAL
DECLARE @b DECIMAL
DECLARE @c DECIMAL
DECLARE @d DECIMAL
DECLARE @e DECIMAL
DECLARE @M DECIMAL
DECLARE @N DECIMAL
DECLARE @giorno DECIMAL
DECLARE @mese DECIMAL
DECLARE @pasqua DATETIME

  IF (@Anno <= 2099) BEGIN
        SET @M = 24;
        SET @N = 5;
  END ELSE IF (@Anno <= 2199) BEGIN
       SET @M = 24;
       SET @N = 6;
  END ELSE IF  (@Anno <= 2299) BEGIN
        SET @M = 25;
        SET @N = 0;
  END ELSE IF  (@Anno <= 2399) BEGIN
        SET @M = 26;
        SET @N = 1;
  END ELSE IF  (@Anno <= 2499) BEGIN
        SET @M = 25;
        SET @N = 1;
  END
  
  SET @a = @Anno % 19;
  SET @b = @Anno % 4;
  SET @c = @Anno % 7;
  SET @d = ((19*@a) + @M) % 30;
  SET @e = ((2*@b) + (4*@c) + (6*@d) + @N) % 7;
  IF ((@d + @e) < 10) BEGIN
       SET @giorno = @d+@e+22;
       SET @mese = 3;
  END ELSE BEGIN
       SET @giorno = @d+@e-9;
       SET @mese = 4;
  END
  IF (@giorno=26 AND @mese=4) BEGIN
       SET @giorno = 19;
       SET @mese = 4;
  END
  IF (@giorno=25 AND @mese=4 AND @d=28 AND @e=6 AND @a>10) BEGIN
        SET @giorno=18;
        SET @mese=4;
  END
  
 SELECT @pasqua = dateadd(mm,(@Anno-1900)* 12 + @mese - 1,0) + (@giorno-1)
 return @pasqua
END


  declare a decimal;
  declare b decimal;
  declare c decimal;
  declare d decimal;
  declare e decimal;
  declare M decimal;
  declare N decimal;
  declare giorno decimal;
  declare mese decimal;
  if (Y <= 2099) then
        set M = 24;
        set N = 5;
  elseif (Y <= 2199) then
       set M = 24;
       set  N = 6;
  elseif (Y <= 2299) then
        set M = 25;
        set N = 0;
  elseif (Y <= 2399) then
        set M = 26;
        set N = 1;
  elseif (Y <= 2499) then
        set M = 25;
        set N = 1;
  end if;
  set a = mod(Y,19);
  set b = mod(Y,4);
  set c = mod(Y,7);
  set d = mod( ((19*a) + M) , 30);
  set e = mod( ((2*b) + (4*c) + (6*d) + N) , 7);
  if ((d + e) < 10) then
       set giorno = d+e+22;
       set mese = 3;
  else
       set giorno = d+e-9;
       set mese = 4;
  end if;
  if (giorno=26 and mese=4) then
       set giorno = 19;
       set mese = 4;
  end if;
  if (giorno=25 and mese=4 and d=28 and e=6 and a>10) then
        set giorno=18;
        set mese=4;
  end if;
 function DataPasqua ($Y) {
 
 // LA DATA IN INGRESSO DEVE ESSERE IN FORMATO YYYY
 
 if ($Y<1583) { 
 	return -1; // ANNO NON SUPPORTATO
 }
 elseif ($Y<=1699) { 
 	$M=22;
 	$N=2;
 }
 elseif ($Y<=1799) {
 	$M=23;
 	$N=3;
 }
 elseif ($Y<=1899) {
 	$M=23;
 	$N=4;
 }
 elseif ($Y<=2099) { 
 	$M=24;
 	$N=5;
 }
 elseif ($Y<=2199) {
 	$M=24;
 	$N=6;
 }
 elseif ($Y<=2299) {
 	$M=25;
 	$N=0;
 }
 elseif ($Y<=2399) {
 	$M=26;
 	$N=1;
 }
 elseif ($Y<=2499) {
 	$M=25;
 	$N=1;
 }
 else {
 	return -1; // ANNO NON SUPPORTATO
 }
 
 
 // APPLICO LALGORITMO PER IL CALCOLO DELLA DATA DI PASQUA
 
 $a = ($Y)%19;
 $b = ($Y)%4;
 $c = ($Y)%7;
 $d = ((19*($a))+$M)%30;
 $e = ((2*($b)) + (4*($c)) + (6*($d)) + $N)%7;
 
 if (($d + $e) < 10) {
 	$giorno = $d+$e+22;
 	$mese = 3;
 }
 else {
 	$giorno = $d+$e-9;
 	$mese = 4;
 } 
 
 // ECCEZIONI
 
 if (($giorno == 26) && ($mese == 4)) {
 	$giorno = 19;
 	$mese = 4;
 }
 
 if (($giorno == 25) && ($mese == 4) && ($d == 28) && ($e == 6) && ($a>10)) {
 	$giorno = 18;
 	$mese = 4;
 }
 
 // LA FUNZIONE RESTITUISCE LA DATA IN FORMATO GGMMYYYY
 
 $ris = "";
 if ($giorno<10) $ris="0";
 $ris = $ris .$giorno."0".$mese.$Y;
 
 return $ris;
 
 }
def pasqua(anno):
  if anno<1583 or anno>2499: return None
  tabella={15:(22, 2), 16:(22, 2), 17:(23, 3), 18:(23, 4), 19:(24, 5),
           20:(24, 5), 21:(24, 6), 22:(25, 0), 23:(26, 1), 24:(25, 1)}
  m, n = tabella[anno//100]
  a=anno%19
  b=anno%4
  c=anno%7
  d=(19*a+m)%30
  e=(2*b+4*c+6*d+n)%7
  giorno=d+e
  if (d+e<10):
    giorno+=22
    mese=3
  else:
    giorno-=9
    mese=4
    if ((giorno==26) or ((giorno==25) and (d==28) and (e==6) and (a>10))):
      giorno-=7
  return giorno, mese, anno
DECLARE
   a        DECIMAL;
   b        DECIMAL;
   c        DECIMAL;
   d        DECIMAL;
   e        DECIMAL;
   m        DECIMAL;
   n        DECIMAL;
   giorno   DECIMAL;
   mese     DECIMAL;
   y        NUMBER  := &anno;
   pasqua   DATE;
BEGIN
   IF ( y <= 2099 ) THEN
      m    := 24;
      n    := 5;
   ELSIF( y <= 2199 ) THEN
      m    := 24;
      n    := 6;
   ELSIF( y <= 2299 ) THEN
      m    := 25;
      n    := 0;
   ELSIF( y <= 2399 ) THEN
      m    := 26;
      n    := 1;
   ELSIF( y <= 2499 ) THEN
      m    := 25;
      n    := 1;
   END IF;

   a         := MOD( y, 19 );
   b         := MOD( y, 4 );
   c         := MOD( y, 7 );
   d         := MOD(  (  ( 19 * a ) + m ), 30 );
   e         := MOD(  (  ( 2 * b ) +( 4 * c ) +( 6 * d ) + n ), 7 );

   IF (  ( d + e ) < 10 ) THEN
      giorno    := d + e + 22;
      mese      := 3;
   ELSE
      giorno    := d + e - 9;
      mese      := 4;
   END IF;

   IF (     giorno = 26
        AND mese = 4 ) THEN
      giorno    := 19;
      mese      := 4;
   END IF;

   IF (     giorno = 25
        AND mese = 4
        AND d = 28
        AND e = 6
        AND a > 10 ) THEN
      giorno    := 18;
      mese      := 4;
   END IF;

   pasqua    := TO_DATE( giorno || '/' || mese || '/' || y, 'dd/mm/rrrr' );
   DBMS_OUTPUT.put_line( 'Pasqua -> ' || TO_CHAR( pasqua, 'dd/mm/rrrr' ) );
END;
#!/bin/bash

if [ $1 ]; then
	anno=$1
else
	read -p "Inserire l'anno per il quale calcolare la pasqua: " anno
fi

let a=$anno%19
let b=$anno%4
let c=$anno%7

if [ $anno -ge 1583 ] && [ $anno -le 1699 ];
then
	m=22
	n=2
elif [ $anno -ge 1700 ] && [ $anno -le 1799 ];
then
	m=23
	n=3
elif [ $anno -ge 1800 ] && [ $anno -le 1899 ];
then
	m=23
	n=4
elif [ $anno -ge 1900 ] && [ $anno -le 2099 ];
then
	m=24
	n=5
elif [ $anno -ge 2100 ] && [ $anno -le 2199 ];
then
	m=24
	n=6
elif [ $anno -ge 2200 ] && [ $anno -le 2299 ];
then
	m=25
	n=0
elif [ $anno -ge 2300 ] && [ $anno -le 2399 ];
then
	m=26
	n=1
elif [ $anno -ge 2400 ] && [ $anno -le 2499 ];
then
	m=25
	n=1
fi

let d=(19*$a+$m)%30
let e=(2*$b+4*$c+6*$d+$n)%7

let appo=$d+$e
if [ $appo -lt 10 ];
then
	let giorno=$d+$e+22
	if [ $giorno -lt 10 ];
	then
		giorno=0$giorno
	fi

	data=$giorno/03/$anno
else
	let giorno=$d+$e-9

	if [ $giorno -eq 26 ];
	then
		giorno=19
	fi
	if [ 25 == $giorno ] && [ 28 == $d ] && [ $e == 6 ] && [ $a > 10 ];
	then
		giorno=18
	fi

	if [ $giorno -lt 10 ];
	then
		giorno=0$giorno
	fi

	data=$giorno/04/$anno
fi
echo $data
#!/usr/bin/perl
use integer;

print "inserisci l'anno: ";
$anno = <>;
chomp $anno;
$a = $anno/100;
$b = $anno-19*($anno/19);
$c = ($a-17)/25;
$d = $a-$a/4-($a-$c)/3+19*$b+15;
$d = $d-30*($d/30);
$d = $d-($d/28)*(1-($d/28)*(29/($d+1))*((21-$b)/11));
$e = $anno+$anno/4+$d+2-$a+$a/4;
$e = $e-7*($e/7);
$z = $d-$e;

$mese = 3+($z+40)/44;
$giorno = $z+28-31*($mese/4);

print "Nell'anno $anno la pasqua cade il giorno $giorno del mese $mese\n";
exit(0);
Private Function CalcolaPasqua(Anno As Integer) As Date
Dim a As Double
Dim b As Double
Dim c As Double
Dim d As Double
Dim e As Double
Dim m As Double
Dim n As Double
Dim giorno As Double
Dim mese As Double
   
   If (Anno <= 2099) Then
      m = 24
      n = 5
   ElseIf (Anno <= 2199) Then
      m = 24
      n = 6
   ElseIf (Anno <= 2299) Then
      m = 25
      n = 0
   ElseIf (Anno <= 2399) Then
      m = 26
      n = 1
   ElseIf (Anno <= 2499) Then
      m = 25
      n = 1
   End If
 
   a = Anno Mod 19
   b = Anno Mod 4
   c = Anno Mod 7
   d = ((19 * a) + m) Mod 30
   e = ((2 * b) + (4 * c) + (6 * d) + n) Mod 7
 
   If ((d + e) < 10) Then
      giorno = d + e + 22
      mese = 3
   Else
      giorno = d + e - 9
      mese = 4
   End If
 
   If (giorno = 26 And mese = 4) Then
      giorno = 19
      mese = 4
   End If
 
   If (giorno = 25 And mese = 4 And d = 28 And e = 6 And a > 10) Then
      giorno = 18
      mese = 4
   End If
 
   return dateserial(Anno, mese, giorno)   
End Function

 Piccola nota per il Visual Basic 6:
 Lultima riga (prima di End Function) dovrebbe essere:
   CalcolaPasqua = dateserial(Anno, mese, giorno)
 Cioè il valore di ritorno è il nome della funzione stessa.
      ****************************************************************
      *Autore:    R
      *Date:      24-Feb-2014
      * Dato l'anno calcola  la data della Pasqua
      ****************************************************************
       identification division.
       program-id. easter.
      *
       data division.
       working-storage section.
       01 w-a    pic 9(008) usage comp-x value 0.
       01 w-b    pic 9(008) value 0.
       01 w-c    pic 9(008) value 0.
       01 w-d    pic 9(008) value 0.
       01 w-z    pic 9(008) value 0.
       01 w-f    pic 9(008) value 0.
       01 w-g    pic 9(008) value 0.
       01 w-h    pic 9(008) value 0.
       01 w-i    pic 9(008) value 0.
       01 w-j    pic 9(008) value 0.
       01 w-mm   pic 9(002) value 0.
       01 w-gg   pic 9(002) value 0.
       01 w-x    pic 9(008) value 0.
      *
      ****************************************************************
      *
      *linkage   section.
       01 lk-year                   pic 9(004).
       01 lk-easter-date            pic 9(008).
       01 lk-status                 pic s9(02).
      *
      ****************************************************************
      *
      *procedure division using lk-year lk-easter-date lk-status.
       procedure division.
      *
       l-begin.
           move 2015 to lk-year.
           move 0 to lk-easter-date
           move 0 to lk-status
      *
           if  lk-year not numeric
               move zeros to lk-year
               move 01    to lk-status
               go to l-end.
      *
           if  lk-year < 1580
            or lk-year > 2050
               move zeros to lk-year
               move 02    to lk-status
               go to l-end.
      *
       l-calcolate.
      *
      *
            move function mod(lk-year 19) to w-a
      *     divide  lk-year by  19 giving w-x
      *             remainder w-a
      *
            divide  lk-year by 100 giving w-b
                    remainder w-c
      *
            divide  w-b    by   4 giving w-d
                    remainder w-z
      *
            compute w-f = (w-b + 8) / 25
      *
            compute w-g = (w-b - w-f + 1) / 3
      *
            compute w-h = (19 * w-a) + w-b - w-d - w-g + 15
      *
            compute w-h = function mod(w-h 30)
      *
            divide  w-c by 4 giving w-i remainder w-j
      *
            compute w-c = (w-z + w-i) * 2 + 32 - w-h - w-j
      *
            compute w-c = function mod(w-c 7)
      *
            compute w-b = (w-a + (11 * w-h) + (22 * w-c)) / 451.
      *
            compute w-a = w-h + w-c - (7 * w-b) + 114
      *
            compute w-gg = function mod(w-a 31) + 1
      *
            divide  w-a    by  31 giving w-mm

            string lk-year
                    w-mm
                    w-gg delimited by size
                    into lk-easter-date.
       l-end.
            exit program.
            stop run.
      *
      ******************************************************************
       end program easter.
 public class EasterCalculation
    {
        private class CalendarConstants
        {
            public int? minDate { get; set; }
            public int maxDate { get; set; }
            public int x { get; set; } 
            public int y { get; set; }
        }
        private static IEnumerable<CalendarConstants> Costanti = new List<CalendarConstants>()
        {
           new CalendarConstants() { minDate = null , maxDate = 1582, x = 15, y= 6 },
	       new CalendarConstants()  { minDate = 1583 , maxDate = 1699, x = 22, y= 2 },
	       new CalendarConstants()  { minDate = 1700 , maxDate = 1799, x = 23, y= 3 },
	       new CalendarConstants()  { minDate = 1800 , maxDate = 1899, x = 23, y= 4 },
	       new CalendarConstants()  { minDate = 1900 , maxDate = 2099, x = 24, y= 5 },
	       new CalendarConstants()  { minDate = 2100 , maxDate = 2199, x = 24, y= 6 },
	       new CalendarConstants()  { minDate = 2200 , maxDate = 2299, x = 25, y= 7 },
           new CalendarConstants()  { minDate = 2300 , maxDate = 2399, x = 26, y= 1 },
           new CalendarConstants()  { minDate = 2400 , maxDate = 2499, x = 25, y= 1 }
        };
        public static DateTime? GetEasterDate(int year)
        {
            var constant = Costanti.First(cx =>
                (!cx.minDate.HasValue || year >= cx.minDate.Value) &&
                (year <= cx.maxDate));
            var x = constant.x;
            var y = constant.y;
            var a = year % 19;
            var b = year % 4;
            var c = year % 7;
            var d = (19 * a + x) % 30;
            var e = (2 * b + 4 * c + 6 * d + y) % 7;
            var sum = 22 + d + e;
            if (sum <= 31) return new DateTime(year, 3, sum);
            else if (((sum - 31) != 26 && (sum - 31) != 25) ||
                        ((sum - 31) == 25 && (d != 28 || a <= 10)))
                return new DateTime(year, 4, sum - 31);
            else if ((sum - 31) == 25 && d == 28 && a > 10) return new DateTime(year, 4, 18);
            else return new DateTime(year, 4, 19);

        }
    }

Altri progetti

modifica