Diferencia entre revisiones de «Computus»

De Wikipedia, la enciclopedia libre
Contenido eliminado Contenido añadido
m Revertidos los cambios de 189.186.85.230 (disc.) a la última edición de 85.85.49.228
Línea 326: Línea 326:
</source>
</source>
Ejemplo en: http://www.nightmx.com/pascua.php [Louis Palovits]
Ejemplo en: http://www.nightmx.com/pascua.php [Louis Palovits]



=== Algoritmo en Turbo Pascal ===
=== Algoritmo en Turbo Pascal ===

Revisión del 17:34 23 abr 2009

Dionisio el Exiguo inventó la era Anno Domini para calcular la fecha de Pascua.
Tabla hallada en Suecia con las fechas de las Pascuas del años 1140 al 1671 usando el calendario juliano, escritas en rúnico.

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.

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.

Cálculo

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 ano;
    
    /** Creates a new instance of Pascua */
    public Pascua(int ano) {
        if (ano >= 1583 && ano <= 1699){
            M = 22;
            N = 2;
        }else if ( ano >=1700 && ano <= 1799){
            M = 23;
            N = 3;
        }else if ( ano >=1800 && ano <= 1899){
            M = 23;
            N = 4;
        }else if ( ano >=1900 && ano <=2099){
            M = 24;
            N = 5;
        }else if ( ano >=2100 && ano <=2199){
            M= 24;
            N= 6;
        }else if ( ano>=2200 && ano <= 2299){
            M= 25;
            N= 0;
        }
        this.ano = ano;
    }
    
    
    public  Date getFechaPascua(){
    int a,b,c,d,e,dia,mes;
    
    
    //Cálculo de residuos
    a = ano % 19;
    b = ano % 4;
    c = ano % 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.ano);
    
    
    
    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
  ano, a, b, c, d, e, res, F, G: integer;
    begin
    clrscr;
    Textmode(12);
    Textcolor(10);
    write('Ingrese número de a¤o entre 1900 y 2099: ');
    readln (ano);
     a:= ano mod 20;
     b:= ano mod 0;
     c:= ano 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 ',ano,' es: ', F , ' de Marzo ', ano);
      gotoxy(15,17);
      writeln('La fecha del Viernes Santo ',ano,' es: ', F-2 , ' de Marzo ', ano);
      readln;
           end
           else
             begin
             gotoxy(15,14);
             writeln('La fecha de La Pascua ',ano, ' es: ', G , ' de Abril ', ano);
             gotoxy(15,17);
             writeln('La fecha del Viernes Santo ',ano, ' es: ', G-2 , ' de Abril ', ano);
             readln;
      end;
        if G=2 then
        begin
        gotoxy(15,19);
        writeln('La fecha CORRECTA del Viernes Santo ',ano, ' es: ', 31 , ' de Marzo ', ano);
        readln;
        end;
           if G=1 then
           begin
           gotoxy(15,19);
           writeln('La fecha CORRECTA del Viernes Santo ',ano, ' es: ', 30 , ' de Marzo ', ano);
           readln;
           end;
             if G= 26 then
             begin
             gotoxy(15,19);
             writeln ('La fecha de CORRECTA de la Pascua ',ano, ' es: 19 de Abril');
             gotoxy(15,20);
             writeln ('La fecha del CORRECTA del Viernes Santo ',ano, ' 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

Enlaces externos