Computus
El Computus es el cálculo de la fecha de Pascua. A principios del siglo IV había en la cristiandad una gran confusión sobre cuándo había de celebrarse la Pascua cristiana o de Pascua de Resurrección, con motivo del aniversario de la resurrección de Jesús de Nazaret. Habían surgido en aquel momento numerosas tendencias o grupos de practicantes que utilizaban cálculos propios.
Antecedentes
Ya en el Concilio de Arlés (en el año 314), se obligó a toda la Cristiandad a celebrar la Pascua el mismo día, y que esta fecha habría de ser fijada por el papa, que enviaría epístolas a todas las iglesias del orbe con las instrucciones necesarias. Sin embargo, no todas las congregaciones siguieron estos preceptos.
Concilio de Nicea
Es en el Concilio de Nicea (en el año 325) donde se llega finalmente a una solución para este asunto.
En él se estableció que la Pascua de Resurrección había de ser celebrada cumpliendo unas determinadas normas:
- Que la Pascua se celebrase en domingo.
- Que no coincidiese nunca con la Pascua judía, que se celebraba independientemente del día de la semana. (De esta manera se evitarían paralelismos o confusiones entre ambas religiones).
- Que los cristianos no celebrasen nunca la Pascua dos veces en el mismo año. Esto tiene su explicación porque el año nuevo empezaba en el equinoccio primaveral, por lo que se prohibía la celebración de la Pascua antes del equinoccio real (antes de la entrada del Sol en Aries).
No obstante, siguió habiendo diferencias entre la Iglesia de Roma y la Iglesia de Alejandría, si bien el Concilio de Nicea dio la razón a los alejandrinos, estableciéndose la costumbre de que la fecha de la Pascua se calculaba en Alejandría, que lo comunicaba a Roma, la cual difundía el cálculo al resto de la cristiandad.
Pese a este acuerdo formal, las discrepancias continuaron por razones astronómicas. La Iglesia romana consideraba que el equinoccio de primavera era el 18 de marzo y para calcular la edad de la Luna (epacta) utilizaban un ciclo de 84 años. Los alejandrinos para el cálculo de la edad de la Luna usaban el famoso ciclo metónico de 19 años. Estas diferencias, y otras menores, hacían que en la Iglesia romana nunca cayera con posterioridad al 21 de abril, mientras que el alejandrina podía llegar a ser el 25.
Dionisio el Exiguo
Finalmente fue Dionisio el Exiguo (en el año 525) quien desde Roma convenció de las bondades del cálculo alejandrino, unificándose al fin el cálculo de la pascua cristiana.
Para el cálculo hay que establecer unas premisas iniciales:
- La Pascua ha de caer en domingo.
- Este domingo ha de ser el siguiente al plenilunio pascual (la primera luna llena de la primavera boreal). Si esta fecha cayese en domingo, la Pascua se trasladará al domingo siguiente para evitar la coincidencia con la Pascua judía.
- La luna pascual es aquella cuyo plenilunio tiene lugar en el equinoccio de primavera (vernal) del hemisferio norte (de otoño en el sur) o inmediatamente después.
- Este equinoccio tiene lugar el 21 de marzo.
- Llamamos epacta a la edad lunar. En concreto nos interesa para este cálculo la epacta del año, la diferencia en días que el año solar excede al año lunar. O dicho más fácilmente, el día del ciclo lunar en que está la Luna el 1 de enero del año cuya Pascua estamos calculando. Este número —como es lógico— varía entre 0 y 29.
Antes de proseguir es preciso dejar claro que en términos astronómicos, el equinoccio puede tener lugar el 20 o el 19 de marzo, si bien en el calendario gregoriano se establecen unas fechas astronómicas que, aún difiriendo ligeramente de las fechas astronómicas reales, son las que se emplean para el cálculo.
Así las cosas, queda claro que la Pascua de Resurrección no puede ser antes del 22 de marzo (en caso de que el 21 y plenilunio fuese sábado), y tampoco puede ser más tarde del 25 de abril, (suponiendo que el 21 de marzo fuese el día siguiente al plenilunio, habría que esperar una lunación completa (29 días) para llegar al siguiente plenilunio, que sería el 18 de abril, el cual, si cayese en domingo, desplazaría la Pascua una semana para evitar la coincidencia con la pascua judía, quedando: 18 + 7 el 25 de abril)
Si bien durante el Renacimiento se extrajeron tablas de cálculo para la Pascua en función del número áureo y otras más complejas, hoy en día la fórmula más sencilla de calcular esta fecha es mediante la fórmula desarrollada por el matemático Gauss.
Cálculo
Definamos 5 variables, a, b, c, d, y e. Además de dos constantes M y N, que para los años comprendidos entre 1900 y 2100 tomarán los valores 24 y 5 respectivamente. Llamaremos A al año del que queremos calcular la Pascua.
- a es el resto de la división , o técnicamente según la Aritmética modular diríamos ,
- b es el resto de la división ,
- c es el resto de la división ,
- d es el resto de la división ,
- e es el resto de la división .
Si d + e < 10, entonces la Pascua caerá en el día (d + e + 22) de marzo. En caso contrario (d + e > 9), caerá en el día (d + e − 9) de abril.
Existen dos excepciones a tener en cuenta:
- Si la fecha obtenida es el 26 de abril, entonces la Pascua caerá en el 19 de abril.
- Si la fecha obtenida es el 25 de abril, con d = 28, e = 6 y a > 10, entonces la Pascua caerá en el 18 de abril.
Los valores de M y N para años anteriores a 1900 o posteriores a 2100 pueden obtenerse de la tabla siguiente:
Años M N 1583-1699 22 2 1700-1799 23 3 1800-1899 23 4 1900-2099 24 5 2100-2199 24 6 2200-2299 25 0
Ejemplo
Para comprobar la fórmula, calcularemos la fecha del domingo de Resurrección del año 2007
- A = 2007
- M = 24
- N = 5
- a = resto de = 12
- b = resto de = 3
- c = resto de = 5
- d = resto de = 12
- e = resto de = 5
Como "d" + "e" = 17 > 9, habremos de utilizar la segunda de las fórmulas (la correspondiente a abril), la cual da como resultado 8. El domingo 8 de abril de 2007 es domingo de Resurrección.
Implementación del algoritmo
Algoritmo en Java
import java.util.Date;
import java.util.Calendar;
public class Pascua {
private static int M=24;
private static int N=5;
private int anno;
/** Creates a new instance of Pascua */
public Pascua(int anno) {
if (anno >= 1583 && anno <= 1699){
M = 22;
N = 2;
}else if ( anno >=1700 && anno <= 1799){
M = 23;
N = 3;
}else if ( anno >=1800 && anno <= 1899){
M = 23;
N = 4;
}else if ( anno >=1900 && anno <=2099){
M = 24;
N = 5;
}else if ( anno >=2100 && anno <=2199){
M= 24;
N= 6;
}else if ( anno>=2200 && anno <= 2299){
M= 25;
N= 0;
}
this.anno = anno;
}
public Date getFechaPascua(){
int a,b,c,d,e,dia,mes;
//Cálculo de residuos
a = anno % 19;
b = anno % 4;
c = anno % 7;
d = (19*a + M) % 30;
e = (2*b+4*c+6*d + N) % 7;
// Decidir entre los 2 casos:
if (d+e < 10) {
dia = d+e+22;
mes = Calendar.MARCH;
}else{
dia = d+e-9;
mes = Calendar.APRIL;
}
// Excepciones especiales (según artículo)
if (dia == 26 && mes == Calendar.APRIL)
dia = 19;
if (dia == 25 && mes == Calendar.APRIL && d==28 && e == 6 && a >10)
dia = 18;
Calendar fechaPascua = Calendar.getInstance();
fechaPascua.set(Calendar.DAY_OF_MONTH,dia);
fechaPascua.set(Calendar.MONTH,mes);
fechaPascua.set(Calendar.YEAR,this.anno);
return fechaPascua.getTime();
}
public static void main (String [] args){
Pascua pascua = new Pascua(2009);
System.out.println(java.text.DateFormat.getDateInstance().format(pascua.getFechaPascua()));
}
}
Esta es la salida al ejecutar el código anterior.
12/04/2009
Algoritmo en Python
La siguiente es una implementación del algoritmo anterior en el lenguaje Python, siguiendo fielmente los pasos descritos en el algoritmo anterior.
#coding: latin-1
def Pascua(anno):
# Constantes mágicas
M = 24
N = 5
#Cálculo de residuos
a = anno % 19
b = anno % 4
c = anno % 7
d = (19*a + M) % 30
e = (2*b+4*c+6*d + N) % 7
# Decidir entre los 2 casos:
if d+e < 10 :
dia = d+e+22
mes = "marzo"
else:
dia = d+e-9
mes = "abril"
# Excepciones especiales (según artículo)
if dia == 26 and mes == "abril":
dia = 19
if dia == 25 and mes == "abril" and d==28 and e == 6 and a >10:
dia = 18
return [dia, mes, anno]
print Pascua(2008)
El resultado de ejecutar el programa anterior sería
[23, 'marzo',2008]
Algoritmo en Perl
Tomando el algoritmo anterior y pasándolo al lenguaje Perl, Tendríamos algo así:
#perl
#ejecutarlo pasando el año como parámetro.
printf "La pascua es: %s %s %d\n", Pascua( shift );
sub Pascua {
# Constantes mágicas
$M = 24;
$N = 5;
$anno = shift;
#Cálculo de residuos
$a = $anno % 19;
$b = $anno % 4;
$c = $anno % 7;
$d = (19*$a + $M) % 30;
$e = (2*$b+4*$c+6*$d + $N) % 7;
# Decidir entre los 2 casos:
if ( $d + $e < 10 ) {
$dia = $d + $e + 22;
$mes = "marzo";
}
else {
$dia = $d + $e - 9;
$mes = "abril";
}
# Excepciones especiales (según artículo)
if ( $dia == 26 and $mes == "abril" ) {
$dia = 19;
}
if ( $dia == 25 and $mes == "abril" and $d==28 and $e == 6 and $a >10 ) {
$dia = 18;
}
return ( $dia, $mes, $anno );
}
El resultado de ejecutar: % perl pascua.pl 2008
La pascua es: 23 marzo 2008
Algoritmo en PHP
Tomando los algoritmos anteriores e implementandolo en PHP con salida a HTML tenemos:
<?
function pascua ($anno){
# Constantes mágicas
$M = 24;
$N = 5;
#Cálculo de residuos
$a = $anno % 19;
$b = $anno % 4;
$c = $anno % 7;
$d = (19*$a + $M) % 30;
$e = (2*$b+4*$c+6*$d + $N) % 7;
# Decidir entre los 2 casos:
if ( $d + $e < 10 ) {
$dia = $d + $e + 22;
$mes = "marzo";
}
else {
$dia = $d + $e - 9;
$mes = "abril";
}
# Excepciones especiales (según artículo)
if ( $dia == 26 and $mes == "abril" ) {
$dia = 19;
}
if ( $dia == 25 and $mes == "abril" and $d==28 and $e == 6 and $a >10 ) {
$dia = 18;
}
$ret = $dia.'-'.$mes.'-'.$anno;
return ($ret);
}
?>
<center>
<form action="pascua.php" name="forma" method="post">
<font face="Arial, Helvetica, sans-serif" size="2">
Año: <input type="text" name="anno" size="5" maxlength="4">
<input type="submit" name="Go!" value="Go!">
</font>
</form>
</center>
<?php
#perl
#ejecutarlo pasando el año como parámetro.
if ($_POST[anno] != NULL) {
$fecha = explode('-',pascua($_POST[anno]));
print "<div align=center><font face=arial>
La pascua (domingo de resurrección)
en el año introducido es el: $fecha[0] de $fecha[1] de $fecha[2]
</font></div>";
}
?>
Ejemplo en: http://www.nightmx.com/pascua.php [Louis Palovits]
Algoritmo en Turbo Pascal
program fechadesemanasanta;
uses crt;
var
anno, a, b, c, d, e, res, F, G: integer;
begin
clrscr;
Textmode(12);
Textcolor(10);
write('Ingrese número de anno entre 1900 y 2099: ');
readln (anno);
a:= anno mod 20;
b:= anno mod 0;
c:= anno mod 8;
d:= (19*a + 24) mod 30;
e:= (2*b + 4*c + 6*d + 5) mod 7;
writeln('Resultado de A es: ', a);
writeln('Resultado de B es: ', b);
writeln('Resultado de C es: ', c);
writeln('Resultado de D es: ', d);
writeln('Resultado de E es: ', e);
res:= d+e;
writeln('Resultado de D+E es: ', res);
readln;
F:= res + 22;
G:= res - 9;
writeln('Resultado de F es: ', F);
writeln('Resultado de G es: ', G);
if res<10 then
begin
gotoxy(15,14);
writeln('La fecha de La Pascua ',anno,' es: ', F , ' de Marzo ', anno);
gotoxy(15,17);
writeln('La fecha del Viernes Santo ',anno,' es: ', F-2 , ' de Marzo ', anno);
readln;
end
else
begin
gotoxy(15,14);
writeln('La fecha de La Pascua ',anno, ' es: ', G , ' de Abril ', anno);
gotoxy(15,17);
writeln('La fecha del Viernes Santo ',anno, ' es: ', G-2 , ' de Abril ', anno);
readln;
end;
if G=2 then
begin
gotoxy(15,19);
writeln('La fecha CORRECTA del Viernes Santo ',anno, ' es: ', 31 , ' de Marzo ', anno);
readln;
end;
if G=1 then
begin
gotoxy(15,19);
writeln('La fecha CORRECTA del Viernes Santo ',anno, ' es: ', 30 , ' de Marzo ', anno);
readln;
end;
if G= 26 then
begin
gotoxy(15,19);
writeln ('La fecha de CORRECTA de la Pascua ',anno, ' es: 19 de Abril');
gotoxy(15,20);
writeln ('La fecha del CORRECTA del Viernes Santo ',anno, ' es: 17 de Abril');
gotoxy(1,22);
writeln ('Ya que la Fecha de Pascua puede variar entre el 22 de Marzo y el 25 de Abril');
readln;
end;
if G=25 then
if d=28 then
if e=6 then
if a>10 then
begin
gotoxy(15,19);
writeln ('La fecha CORRECTA de la Pascua es: 18 de Abril');
gotoxy(15,20);
writeln ('La fecha CORRECTA del Viernes Santo es: 16 de Abril');
gotoxy(15,22);
writeln ('Puesto que los resultados de G:25 con D:28 E:6 y A>10');
gotoxy(15,23);
writeln ('Ignorar esta nota si algún resultado NO concuerda ');
readln;
end;
end.
Algortimo en pl/pgsql de postgresql
CREATE OR REPLACE FUNCTION p_fecha_pascua(
iv_ano text, -- Año a calcular
out iv_fecpascua date -- Fecha de salida
)
AS
$BODY$
DECLARE
p_m int := 24;
p_n int := 5;
p_a int;
p_b int;
p_c int;
p_d int;
p_e int;
p_dia int;
p_mes int;
BEGIN
p_a := iv_ano::integer % 19;
p_b := iv_ano::integer % 4;
p_c := iv_ano::integer % 7;
p_d := (19*p_a + p_m) % 30;
p_e := (2*p_b+4*p_c+6*p_d + p_n) % 7;
if p_d+p_e < 10 then
p_dia := p_d+p_e+22;
p_mes := 3;
else
p_dia := p_d+p_e-9;
p_mes = 4;
end if;
if p_dia = 26 and p_mes = 4 then
p_dia = 19;
elsif p_dia = 25 and p_mes = 4 and p_d=28 and p_e = 6 and p_a >10 then
p_dia = 18;
end if;
iv_fecpascua := to_date(iv_ano ||'/'|| p_mes ||'/'|| p_dia,'yyyy/mm/dd');
end;
$BODY$ LANGUAGE 'plpgsql' volatile;
-- Uso:
select p_fecha_pascua('2012');
Algoritmo en Delphi
function Pascua(Anio: word): TDateTime;
var
a, b, c, d, e, f, g, h, i, k, l, m, n: word;
Mes, Dia: word;
begin
{ Devuelve la fecha del año en la que cae la Pascua de Resurrección.
Se utiliza para ello el Algoritmo de Butcher }
a := anio mod 19;
b := anio div 100;
c := anio mod 100;
d := b div 4;
e := b mod 4;
f := (b + 8) div 25;
g := (b - f + 1) div 3;
h := (19 * a + b - d - g + 15) mod 30;
i := c div 4;
k := c mod 4;
l := (32 + 2 * e + 2 * I - h - k) mod 7;
m := (a + 11 * h - 22 * l) div 451;
n := h + l - 7 * m + 114;
Mes := n div 31;
Dia := 1 + n mod 31;
Result := EncodeDate(Anio, Mes, Dia);
end;
Fuente: http://www.clubdelphi.com/foros/showthread.php?t=30413
Algoritmo en PowerBuilder
//Función: ej. f_calculo_domingo_pascua(ano_a_calcular)
// a_ano=año de cálculo: parámetro(integer) que recibe la función.
// ld_fecha=fecha (date): es la variable que retorna la función.
//
// Proceso de la función:
//
date ld_fecha
// variables de trabajo.
integer a, b, c, d ,e, M, N
IF a_ano >= 1583 and a_ano <= 1699 THEN
M=22
N=2
ELSEIF a_ano >= 1700 AND a_ano <= 1799 THEN
M=23
N=3
ELSEIF a_ano >= 1800 AND a_ano <= 1899 THEN
M=23
N=4
ELSEIF a_ano >= 1900 AND a_ano <= 2099 THEN
M=24
N=5
ELSEIF a_ano >= 2100 AND a_ano <= 2199 THEN
M=24
N=6
ELSEIF a_ano >= 2200 AND a_ano <= 2299 THEN
M=25
N=0
END IF
a=Mod(a_ano,19)
b=Mod(a_ano,4)
c=Mod(a_ano,7)
d=Mod(((19*a) + M),30)
e=Mod(((2*b)+(4*c)+(6*d)+N),7)
//Cálculo de fecha relativa.
IF (d+e) < 10 THEN
// se resta 1 (22 dias -1) porque se toma como base el 1ro. de marzo.
ld_fecha=RelativeDate(date('01/03/'+string(a_ano)),((d+e)+(22 - 1)))
ELSE
// se resta 1 (9 dias -1) porque se toma como base el 1ro. de abril.
ld_fecha=RelativeDate(date('01/04/'+string(a_ano)),(((d+e)-9)-1))
END IF
//Condicionales especiales (excepciones según explicación).
//Existen dos excepciones a tener en cuenta:
//
//Si la fecha obtenida es el 26 de abril...
// la Pascua caerá en el 19 de abril.
//Si la fecha obtenida es el 25 de abril, con d = 28, e = 6 y a > 10.…
// la Pascua caerá en el 18 de abril.
//
IF ld_fecha=date('26/04/'+string(a_ano)) then
ld_fecha=date('19/04/'+string(a_ano))
ELSEIF ld_fecha=date('25/04/'+string(a_ano)) AND d=28 and e = 6 AND a > 10 then
ld_fecha=date('18/04/'+string(a_ano))
END IF
return(ld_fecha)
Create proc pascuass as
declare @fecha datetime declare @di datetime declare @año int declare @m int declare @n int declare @a int declare @b int declare @c int declare @d int declare @e int declare @dia int
select @fecha=getdate() select @año=year(@fecha)
if @año>=1583 and @año<=1699 select @m=22 select @n=2 if @año>=1700 and @año<=1799 select @m=23 select @n=3 if @año>=1800 and @año<=1899 select @m=23 select @n=4 if @año>=1900 and @año<=2099 set @m=24 set @n=5
select @a=@año%19 select @b=@año%4 select @c=@año%7 select @d=(19*@a+@m) %30 select @e=((2*@b)+(4*@c)+(6*@d)+@n)%7
select @dia =22+@e+@d
if @dia<=31 print cast(@dia as varchar(2)) + '/03/'+cast(@año as varchar(4))
if @dia>31 select @dia=@dia-31 print cast(@dia as varchar(2)) + '/04/'+cast(@año as varchar(4)) return