Lo cierto es que este programita tan sencillo, extremadamente monográfico y sectorizado lleva conmigo desde muchos años antes de que a Steve jobs se le ocurriera algo remotamente parecido a un iPhone. Vamos a dar un breve repaso sobre cómo hemos llegado hasta aquí.
Un poco de historia
Esta historia comienza a finales de siglo pasado (siempre quise decirlo). Como os podeis imaginar, aunque internet ya existía de una forma muy parecida a la actual, las personas que teníamos acceso a ella desde casa eramos una minoría que se gastaba un dinero curioso a fin de mes, sin tarifas planas todavía, por una conexión con un modem por RTB a 33’6. No era tan fácil en ese momento encontrar tanta información sobre estas cuestiones como la que puede haber hoy. En este contexto de lentitud, cutrez y desconexiones constantes, es normal que la idea inicial de todo partiera de aplicarle ingeniería inversa a… una agenda-dietario de oficina. Recordareis que, en estos “libros” al final suele haber un mapa de carretera, un santoral y un calendario perpetuo entre otras cosas. Pues tomé el calendario perpetuo de fiestas móviles, que no eran sino una serie de tablas y sus correspondientes pasos para llegar al resultado deseado. No tenia ni pies ni cabeza, pero en un simple ejercicio de racionalización extraje el algoritmo y se me ocurrió implementarlo con Javascript. Todo esto debió suceder ya alrededor de 1999. Lo publiqué en mi web y mi sorpresa fue enorme cuando varios años después, tras buscar en el ya todopoderoso google, había dado la vuelta al mundo.
Tuve la idea, cuando lo publiqué, de poner una especie de licencia que invitaba a que cualquier persona se copiara el script a cambio de una simple atribución de autoría. En la vida imaginé que pudiera haber interesado a nadie, pero la realidad es que se convirtió en un recurso muy extendido entre los webs católicos de todo el mundo.
Ésta es la pinta que tenía en la versión que se personalizó la gente de http://www.lapasion.org con sus “colores”, allá por 2001. Me ha hecho mucha ilusión encontrarmelo en Internet Archive Wayback Machine.
El algoritmo
Resulta que, al cabo de los años, y gracias a las facilidades del internet de hoy en día en el que todo está tan indexado, me entero de que lo que yo estaba usando en aquel entonces se llama Algoritmo de Butcher, y es uno de los varios que hay para realizar este cálculo. Rivaliza con el ideado por el mismísimo Gauss por ser uno de los más empleados. Lo usé en aquella ocasión para implementar mi primer programa en Javascript, y desde entonces lo empleo como mi propio “hola mundo” personal cada vez que me meto a aprender algo nuevo. Os dejo la pinta que tenía mi implementación original.
function calcular()
{
if (verificar(anio)){
A = (anio % 19);
B = (anio % 4);
C = (anio % 7);
D = (( 19 * A + 24 ) % 30);
E = (( 2 * B + 4 * C + 6 * D + 5 ) % 7);
F = 15 + D + E;
if((D+E) > 16){
mes="Abril";
F=F-31;
}
else{
mes="Marzo";
}
resultado=F + " de " + mes;
}
else{
alert("Ha introducido un año incorrecto");
resultado=0;
}
return (resultado);
}
Como puede apreciarse, es más simple que el mecanismo de un cubo. Quizá esa sea una de sus virtudes. Con estas pocas lineas se consigue calcular ni más ni menos que la fecha de la primera luna llena de primavera, conocida como Luna de Nisán en recuerdo al mes del calendario judio. Una vez que se obtiene, se hacen las traslaciones para el cuadre con el día concreto de la semana que corresponde.
Aquí teneis mi implementación en Objetive C, la misma que uso en Moveable Feast.
NSUInteger A = anio % 19;
NSUInteger B = anio / 100;
NSUInteger C = anio % 100;
NSUInteger D = B / 4;
NSUInteger E = B % 4;
NSUInteger F = ( B + 8 ) / 25;
NSUInteger G = (B - F + 1) / 3;
NSUInteger H = ((19 * A) + B - D - G + 15) % 30;
NSUInteger I = C / 4;
NSUInteger K = C % 4;
NSUInteger L = (32 + (2 * E) + (2 * I) - H - K) % 7;
NSUInteger M = (A + (11 * H) + (22 * L)) / 451;
NSUInteger P = H + L - (7 * M) + 114;
[componentes setDay:(NSUInteger)((P % 31) + 1)];
[componentes setMonth:(NSUInteger)(P / 31)];
[componentes setYear:(NSUInteger)anio];
NSCalendar *gregorian
= [[[NSCalendar alloc
] initWithCalendarIdentifier
: NSGregorianCalendar
] autorelease
];
domingoResurreccion = [[gregorian dateFromComponents: componentes] retain];
Como puede apreciarse, las dos versiones no son exactamente iguales. La explicación es que la primera de ellas en Javascript calcula realmente el Domingo de Ramos, y la segunda en Objetive C lo que calcula es el Domingo de Resurrección y usa un desarrollo un poco más largo para evitar el condicional que averigua el mes, que en su día tuve que improvisar yo mismo para el primer caso.
No me enredo más, que esto está quedando ya muy largo y no quiero aburrir a nadie. Aprovecho la ocasión para informaros de que está prácticamente finalizada la primera actualización de Moveable Feasts, que traerá varias novedades que serán comentadas por aquí. Esta semana la enviaré a Apple, y estará disponible en varios días.