Calendario perpetuo
# Calendario perpetuo

Il calendario perpetuo è un metodo che permette di ricavare il giorno della settimana (lunedì, martedì, mercoledì, giovedì, venerdì, sabato, domenica) di una qualsiasi data del calendario.

Sotto forma di algoritmo, uno dei più semplici è l'algoritmo creato da F. Berio consistente nel sommare 5 termini, facendo uso dell'operazione di modulo per ridurre il risultato della somma ad un valore inferiore a 7. Tale operazione (indicata dal simbolo "mod") è analoga all'aritmetica dell'orologio (secondo cui ad es. le ore 15 corrispondono alle ore 3 poiché 15 mod 12 = 3) e consiste nel resto della divisione (quindi 18 mod 7 = 4 poiché 18 / 7 = 2 e il resto della divisione è 4; o, equivalentemente, poiché togliendo 7 due volte da 18, il resto vale 4).

## L'algoritmo

### Calendario gregoriano

Presa una data gg/mm/ssaa, le sue componenti son descritte nella seguente tabella:

| Il numero | corrisponde a | con le limitazioni |
| - | - | - |
| gg | giorno del mese | da 1 a 31 |
| mm | mese dell'anno | da 1 a 12 |
| ss | prime due cifre dell'anno [int(anno / 100)] | da 15 in poi |
| aa | ultime due cifre dell'anno (anno mod 100) | da 0 a 99 |

L'algoritmo consiste nel determinare cinque addendi G, M, S, A, B e nel calcolare [(G + M + S + A + B) mod 7] ; l'operazione di modulo può essere eseguita non solo dopo aver sommato i cinque addendi ma anche, opzionalmente, su qualunque addendo o somma parziale.

Il giorno del mese (modulo 7) fornisce il primo addendo G dell'espressione finale:

* G = gg mod 7

Il secondo addendo M è un codice derivato dal mese, fornito dalla seguente tabella:

| Mese | M (anno non bisestile) | M (anno bisestile) |
| - | - | - |
| Gennaio | 6 | 5 |
| Febbraio | 2 | 1 |
| Marzo | 2 | 2 |
| Aprile | 5 | 5 |
| Maggio | 0 | 0 |
| Giugno | 3 | 3 |
| Luglio | 5 | 5 |
| Agosto | 1 | 1 |
| Settembre | 4 | 4 |
| Ottobre | 6 | 6 |
| Novembre | 2 | 2 |
| Dicembre | 4 | 4 |

Il terzo addendo S è un codice derivato dal secolo, cioè dalle prime due cifre ss dell'anno: ai 4 possibili risultati di "ss mod 4" si associa un numero S tale che:

| ss mod 4 | 0 | 1 | 2 | 3 |
| - | - | - | - | - |
| S | 0 | 5 | 3 | 1 |

e quindi, per i primi secoli nell'ambito di validità del calendario gregoriano, risulta:

| ss | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| - | - | - | - | - | - | - | - | - | - |
| S | 1 | 0 | 5 | 3 | 1 | 0 | 5 | 3 | 1 |

In realtà, al secondo e terzo addendo potrebbero essere attribuite sette combinazioni differenti di valori: la combinazione di valori qui presentata per M ed S è quella ottimizzata per il secolo attuale poiché per ss = 20 si ha S = 0.

Il quarto addendo A si ricava dalle ultime due cifre aa dell'anno; poiché, nell'ambito di uno stesso secolo, i giorni della settimana si ripetono nel calendario gregoriano ogni 28 anni, si considera:

* A = aa mod 28

Il quinto addendo B si ottiene a partire dalle ultime due cifre aa dell'anno, e rappresenta il numero di anni bisestili che sono sicuramente contenuti in aa anni (int indica la funzione parte intera del numero):

* B = int[(aa mod 28) / 4]

Ad esempio, per il 2023 il risultato dell'operazione è 5 poiché 23 contiene 5 blocchi interi di 4 anni ciascuno; aritmeticamente:

    B = int[(23 mod 28) / 4] = int(23 / 4) = 5

Determinati i cinque addendi, si calcola:

* [(G + M + S + A + B) mod 7]

La formula fornisce un numero compreso tra 0 e 6 che indicherà il giorno della settimana:

| Risultato | Giorno |
| - | - |
| 0 | Domenica |
| 1 | Lunedì |
| 2 | Martedì |
| 3 | Mercoledì |
| 4 | Giovedì |
| 5 | Venerdì |
| 6 | Sabato |

I giorni antecedenti il venerdì 15 ottobre 1582, data dell'entrata in vigore del calendario gregoriano, non possono essere calcolati con le tabelle S mostrate sopra poiché era in vigore il calendario giuliano. L'algoritmo rimarrà valido fino all'eventuale futura introduzione di correzioni al calendario gregoriano.

### Calendario giuliano

Per i giorni del calendario giuliano che vanno dall'anno 1 d.C. fino a giovedì 4 ottobre 1582, ultimo giorno in cui tale calendario è rimasto in vigore, si può usare un algoritmo simile al precedente per conoscere il giorno della settimana corrispondente.

Rimane valido il formato della data, gg/mm/ssaa, le cui componenti sono descritte da questa analoga tabella:

| Il numero | corrisponde a | con le limitazioni |
| - | - | - |
| gg | giorno del mese | da 1 a 31 |
| mm | mese dell'anno | da 1 a 12 |
| ss | prime due cifre dell'anno [int(anno / 100)] | da 0 a 15 |
| aa | ultime due cifre dell'anno (anno mod 100) | da 0 a 99 |

L'algoritmo consiste ancora nel determinare i cinque addendi G, M, S, A, B e nel calcolare [(G + M + S + A + B) mod 7].

Il giorno del mese (modulo 7) fornisce il primo addendo G dell'espressione finale:

* G = gg mod 7

Il secondo addendo M è il codice derivato dal mese, in questo caso fornito dalla seguente tabella:

| Mese | M (anno non bisestile) | M (anno bisestile) |
| - | - | - |
| Gennaio | 5 | 4 |
| Febbraio | 1 | 0 |
| Marzo | 1 | 1 |
| Aprile | 4 | 4 |
| Maggio | 6 | 6 |
| Giugno | 2 | 2 |
| Luglio | 4 | 4 |
| Agosto | 0 | 0 |
| Settembre | 3 | 3 |
| Ottobre | 5 | 5 |
| Novembre | 1 | 1 |
| Dicembre | 3 | 3 |

Il terzo addendo S è il codice derivato dal secolo, cioè dalle prime due cifre ss dell'anno. Per la determinazione di tale numero S si rileva la principale differenza rispetto al calendario gregoriano. Il suo valore si calcola a partire dalla formula:

* S = 6 - (ss mod 7)

e quindi per i secoli del calendario giuliano in cui risulta valido tale algoritmo si ottiene:

| ss | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 |
| - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| S | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 6 | 5 |

Il codice S associato al secolo è determinato in modo diverso perché nel calendario giuliano erano considerati bisestili anche gli anni multipli di 100 e non multipli di 400. Per tale ragione ogni secolo comprende 25 anni bisestili e questo fa sì che, da un secolo all'altro, la numerazione si sposti indietro di una unità.

Il quarto addendo A si ricava dalle ultime due cifre aa dell'anno, così come nel precedente algoritmo; si ottiene quindi:

* A = aa mod 28

Anche il quinto addendo B si ottiene come nell'algoritmo precedente a partire dalle ultime due cifre aa dell'anno:

* B = int[(aa mod 28) / 4]

Determinati i cinque addendi, si calcola:

* [(G + M + S + A + B) mod 7]

La formula fornisce un numero compreso tra 0 e 6 che indicherà il giorno della settimana:

| Risultato | Giorno |
| - | - |
| 0 | Domenica |
| 1 | Lunedì |
| 2 | Martedì |
| 3 | Mercoledì |
| 4 | Giovedì |
| 5 | Venerdì |
| 6 | Sabato |

## Esempi

Calendario giuliano

Data: 1º gennaio 1 d.C. (01/01/0001)

* G = 1 (gg = 01, 1 mod 7 = 1)
* M = 5 (gennaio)
* S = 6 (ss = 00, 6 - (0 mod 7) = 6 - 0 = 6)
* A = 1 (aa = 01, 1 mod 28 = 1)
* B = 0 (int[(1 mod 28) / 4] = int(1 / 4) = 0)
* G + M + S + A + B = 1 + 5 + 6 + 1 + 0 = 13
* 13 mod 7 = 6
* Il giorno 1º gennaio 1 d.C. era un sabato

Data: 29 febbraio 700 (29/02/0700)

* G = 1 (gg = 29, 1 mod 7 = 1)
* M = 0 (febbraio, bisestile)
* S = 6 (ss = 07, 6 - (7 mod 7) = 6 - 0 = 6)
* A = 0 (aa = 00, 0 mod 28 = 0)
* B = 0 (int[(0 mod 28) / 4] = int(0 / 4) = 0)
* G + M + S + A + B = 1 + 0 + 6 + 0 + 0 = 7
* 7 mod 7 = 0
* Il giorno 29 febbraio 700 era una domenica

Data: 1º luglio 1114 (01/07/1114)

* G = 1 (gg = 01, 1 mod 7 = 1)
* M = 4 (luglio)
* S = 2 (ss = 11, 6 - (11 mod 7) = 6 - 4 = 2)
* A = 14 (aa = 14, 14 mod 28 = 14)
* B = 3 (int[(14 mod 28) / 4] = int(14 / 4) = 3)
* G + M + S + A + B = 1 + 4 + 2 + 14 + 3 = 24
* 24 mod 7 = 3
* Il giorno 1º luglio 1114 era un mercoledì

Data: 4 ottobre 1582 (04/10/1582)

* G = 4 (gg = 04, 4 mod 7 = 4)
* M = 5 (ottobre)
* S = 5 (ss = 15, 6 - (15 mod 7) = 6 - 1 = 5)
* A = 26 (aa = 82, 82 mod 28 = 26)
* B = 6 (int[(82 mod 28) / 4] = int(26 / 4) = 6)
* G + M + S + A + B = 4 + 5 + 5 + 26 + 6 = 46
* 46 mod 7 = 4
* Il giorno 4 ottobre 1582 era un giovedì (ultimo giorno di validità del calendario giuliano)

Calendario gregoriano

Data: 15 ottobre 1582 (15/10/1582)

* G = 1 (gg = 15, 15 mod 7 = 1)
* M = 6 (ottobre)
* S = 1 (ss = 15, 15 mod 4 = 3)
* A = 26 (aa = 82, 82 mod 28 = 26)
* B = 6 (int[(82 mod 28) / 4] = int(26 / 4) = 6)
* G + M + S + A + B = 1 + 6 + 1 + 26 + 6 = 40
* 40 mod 7 = 5
* Il giorno 15 ottobre 1582 era un venerdì (primo giorno di validità del calendario gregoriano)

Data: 25 febbraio 1800 (25/02/1800)

* G = 4 (gg = 25, 25 mod 7 = 4)
* M = 2 (febbraio)
* S = 3 (ss = 18, 18 mod 4 = 2)
* A = 0 (aa = 00, 0 mod 28 = 0)
* B = 0 (int[(0 mod 28) / 4] = int(0 / 4) = 0)
* G + M + S + A + B = 4 + 2 + 3 + 0 + 0 = 9
* 9 mod 7 = 2
* Il giorno 25 febbraio 1800 era un martedì

Data: 22 ottobre 2008 (22/10/2008)

* G = 1 (gg = 22, 22 mod 7 = 1)
* M = 6 (ottobre)
* S = 0 (ss = 20, 20 mod 4 = 0)
* A = 8 (aa = 08, 8 mod 28 = 8)
* B = 2 (int[(8 mod 28) / 4] = int(8 / 4) = 2)
* G + M + S + A + B = 1 + 6 + 0 + 8 + 2 = 17
* 17 mod 7 = 3
* Il giorno 22 ottobre 2008 era un mercoledì

Data: 15 aprile 2097 (15/04/2097)

* G = 1 (gg = 15, 15 mod 7 = 1)
* M = 5 (aprile)
* S = 0 (ss = 20, 20 mod 4 = 0)
* A = 13 (aa = 97, 97 mod 28 = 13)
* B = 3 (int[(97 mod 28) / 4] = int(13 / 4) = 3)
* G + M + S + A + B = 1 + 5 + 0 + 13 + 3 = 22
* 22 mod 7 = 1
* Il giorno 15 aprile 2097 sarà un lunedì

## Criteri per il calcolo mnemonico

Per eseguire il calcolo mentalmente in modo efficiente, è opportuno in primo luogo memorizzare la tabella che fornisce l'addendo M in una forma autoreferente. Un metodo è memorizzare i nomi dei mesi troncati ad un numero di caratteri coincidente con il codice M (per non confondere i codici 5 e 6 è opportuno spezzare le sigle di 6 caratteri in due parti):

| Mese | M (anno non bisestile) | M (anno bisestile) |
| - | - | - |
| Gennaio | GEN NAI | GEN NAI -1 |
| Febbraio | FE | FE -1 |
| Marzo | MA | MA |
| Aprile | APRIL | APRIL |
| Maggio | . | . |
| Giugno | GIU | GIU |
| Luglio | LUGLI | LUGLI |
| Agosto | A | A |
| Settembre | SETT | SETT |
| Ottobre | OTT OBR | OTT OBR |
| Novembre | NO | NO |
| Dicembre | DICE | DICE |

In secondo luogo è opportuno tener conto che la somma S+A+B (il contributo dovuto all'anno) non varia per un anno intero; quindi, almeno per l'anno corrente, basta memorizzarla ad inizio anno.

In terzo luogo, è opportuno considerare che nell'ambito di un certo secolo (ss costante) il calendario si ripete ogni 28 anni (poiché 28 è minimo comune multiplo di 7 e 4, in cui 7 è la periodicità con cui si ripetono i giorni della settimana e 4 quella con cui si ripetono gli anni bisestili), quindi se l'anno è maggiore o uguale a 28 basta considerare come anno quello ottenuto sottraendo 28 o un suo multiplo (56 o 84).

Inoltre è da tener conto che, appena un addendo o una somma parziale risulta maggiore o uguale a 7, è opportuno sottrarre immediatamente 7 o suoi multipli in modo da minimizzare i valori in gioco. In particolare, il valore 7 risulta equivalente a 0.

Infine, è necessario conoscere la regola che nel calendario gregoriano stabilisce quali anni siano bisestili: se aa è diverso da 0, l'anno è bisestile se aa è divisibile per 4; se aa è uguale a 0 (anni secolari), l'anno è bisestile se ss è divisibile per 4.

Le operazioni da eseguire mentalmente (rapide nonostante l'apparente complessità) sono quindi:

* considerare il numero del giorno; se maggiore o uguale a 7, sottrarre subito il multiplo di 7 più alto possibile;
* sommare il codice del mese fornito in modo autoreferente dal nome del mese; se è gennaio o febbraio e l'anno è bisestile, va sottratto 1 (come da tabella del codice M); se la somma raggiunge o supera 7, sottrarre subito 7;
* sommare il codice del secolo: per il secolo attuale (ss = 20) il codice è 0 (come da tabella del codice S); per il secolo scorso (ss = 19) il codice è 1; se la somma raggiunge o supera 7, sottrarre subito 7;
* considerare l'anno: se è maggiore o uguale a 28 basta considerare come aa l'anno ottenuto sottraendo 28 o un suo multiplo (56 o 84);
* sommare l'anno aa, decurtato eventualmente di un multiplo di 7;
* sommare il numero di anni bisestili che sono sicuramente contenuti in aa: se aa non raggiunge 4 (è inferiore a 4) considerare 0 bisestili, altrimenti se non raggiunge 8 considerare 1 bisestile, altrimenti se non raggiunge 12 considerare 2 bisestili, ecc.; se la somma raggiunge o supera 7, sottrarre 7;
* il numero ottenuto indica il giorno della settimana: 1 = lunedì, 2 = martedì, ..., 6 = sabato, 0 (equivalente a 7) = domenica.

Attraverso gli esempi viene illustrato come procedere operativamente per eseguire il calcolo.

## Esempi di calcolo mnemonico

Si illustrano in questa sezione esempi di calcolo dell'espressione (G + M + S + A + B) mod 7 in modo ottimizzato per essere eseguito mentalmente.

01/01/2003: pensando la data come 1 "GEN NAI" 2003, bisogna sommare 1 (il giorno) + 6 ("GEN NAI"); fin qui si ottiene 7: si sottrae subito 7 e resta 0; si prosegue sommando 0 (per il secolo attuale) + 3 (anno) + 0 (numero di bisestili in 3 anni) = 3, quindi mercoledì.

01/01/2000: pensando la data come 1 "GEN NAI" 2000, bisogna sommare 1 (il giorno) + 5 ("GEN NAI" -1, cioè 6-1 perché il 2000 era bisestile) + 0 (per il secolo attuale) + 0 (anno) + 0 (numero di bisestili in 0 anni) = 6, quindi sabato.

01/01/2004: pensando la data come 1 "GEN NAI" 2004, bisogna sommare 1 (il giorno) + 5 ("GEN NAI" -1 perché il 2004 era bisestile) + 0 (per il secolo attuale) + 4 (anno); fin qui si ottiene 10: si sottrae subito 7 e resta 3; si prosegue sommando 1 (numero di bisestili in 4 anni) = 4, quindi giovedì.

01/03/2000: pensando la data come 1 "MA" 2000, bisogna sommare 1 (il giorno) + 2 ("MA") + 0 (per il secolo attuale) + 0 (anno) + 0 (numero di bisestili in 0 anni) = 3, quindi mercoledì.

08/03/2000: pensando la data come 8 "MA" 2000, si considera 8 (il giorno); si può sottrarre subito 7 e resta 1; si prosegue sommando 2 ("MA") + 0 (per il secolo attuale) + 0 (anno) + 0 (numero di bisestili in 0 anni) = 3, quindi mercoledì.

25/12/2000: pensando la data come 25 "DICE" 2000, si considera 25 (il giorno); si può sottrarre subito 21 (multiplo di 7) e resta 4; si prosegue sommando 4 ("DICE"), ottenendo 8; si può sottrarre subito 7 e resta 1; si prosegue sommando 0 (per il secolo attuale) + 0 (anno) + 0 (numero di bisestili in 0 anni) = 1, quindi lunedì.

01/10/2003: pensando la data come 1 "OTT OBR" 2003, si considera 1 (il giorno) + 6 ("OTT OBR"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 0 (per il secolo attuale) + 3 (anno) + 0 (numero di bisestili in 3 anni) = 3, quindi mercoledì.

01/10/2004: pensando la data come 1 "OTT OBR" 2004, si considera 1 (il giorno) + 6 ("OTT OBR"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 0 (per il secolo attuale) + 4 (anno) + 1 (numero di bisestili in 4 anni) = 5, quindi venerdì.

01/10/2005: pensando la data come 1 "OTT OBR" 2005, si considera 1 (il giorno) + 6 ("OTT OBR"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 0 (per il secolo attuale) + 5 (anno) + 1 (numero di bisestili in 5 anni) = 6, quindi sabato.

19/03/2007: pensando la data come 19 "MA" 2007, si considera 19 (il giorno); si può sottrarre subito 14 (multiplo di 7) e resta 5; si prosegue sommando 2 ("MA"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 0 (per il secolo attuale) + 0 (anno = 7, ma si può sottrarre immediatamente 7) + 1 (numero di bisestili in 7 anni) = 1, quindi lunedì.

19/03/2008: pensando la data come 19 "MA" 2008, si considera 19 (il giorno); si può sottrarre subito 14 (multiplo di 7) e resta 5; si prosegue sommando 2 ("MA"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 0 (per il secolo attuale) + 1 (anno = 8, ma si può sottrarre immediatamente 7) + 2 (numero di bisestili in 8 anni) = 3, quindi mercoledì.

19/03/2036: pensando la data come 19 "MA" 2036, si considera 19 (il giorno); si può sottrarre subito 14 (multiplo di 7) e resta 5; si prosegue sommando 2 ("MA"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 0 (per il secolo attuale); essendo l'anno maggiore o uguale a 28, si sottrae 28 e resta 8 (perché il calendario del 2036 coincide con quello del 2008), quindi si considera per l'anno il valore 8; si prosegue perciò sommando 1 (anno = 8, ma si può sottrarre immediatamente 7) + 2 (numero di bisestili in 8 anni) = 3, quindi mercoledì.

19/03/1936: pensando la data come 19 "MA" 1936, si considera 19 (il giorno); si può sottrarre subito 14 (multiplo di 7) e resta 5; si prosegue sommando 2 ("MA"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 1 (per il secolo scorso); essendo l'anno maggiore o uguale a 28, si sottrae 28 e resta 8 (perché il calendario del 1936 coincide con quello del 1908), quindi si considera per l'anno il valore 8; si prosegue perciò sommando 1 (anno = 8, ma si può sottrarre immediatamente 7) + 2 (numero di bisestili in 8 anni) = 4, quindi giovedì.

31/12/1999: pensando la data come 31 "DICE" 1999, si considera 31 (il giorno); si può sottrarre subito 28 (multiplo di 7) e resta 3; si prosegue sommando 4 ("DICE"), ottenendo 7; si può sottrarre subito 7 e resta 0; si prosegue sommando 1 (per il secolo scorso); essendo l'anno maggiore o uguale a 28, si sottrae un multiplo di 28 (56 o 84, in questo caso 84) e resta 15 (perché il calendario del 1999 coincide con quello del 1915), quindi si considera per l'anno il valore 15; si prosegue perciò sommando 1 (anno = 15, ma si può sottrarre immediatamente 14 che è multiplo di 7) + 3 (numero di bisestili in 15 anni) = 5, quindi venerdì. (Notare che il giorno successivo, 01/01/2000, era sabato).

01/01/2100: pensando la data come 1 "GEN NAI" 2100, bisogna sommare 1 (il giorno) + 6 ("GEN NAI", cioè 6 perché il 2100 non sarà bisestile); fin qui si ottiene 7: si sottrae subito 7 e resta 0; si prosegue sommando 5 (per il prossimo secolo) + 0 (anno) + 0 (numero di bisestili in 0 anni) = 5, quindi venerdì.

## Calendari perpetui storici

Un calendario perpetuo fu costruito nel 1741-1741 per il re di Francia Luigi XV. Composto di quattro pannelli in bronzo dorato al mercurio, ha tasselli mobili in smalto bianco che recano date. Ogni pannello ha una cimasa con le insegne reali e con questa scrittaː«Almanch perpétuel et toujours nouveau dédié au Roi». Ai lati della scritta ci sono il sole e la luna dipinti in oro. Ogni pannello è diviso in verticale in tre parti, una per ogni mese del trimestre. Ogni parte è divisa a sua volta in tre colonne, dotate di tasselli scorrevoli smaltatiː nella prima colonna ci sono i giorni della settimana e le fasi della luna; nella seconda colonna c'è la data in cifra; nella terza colonna ci sono i giorni festivi, insieme al segno zodiacale smaltato e a colori e al nome del mese in bianco e nero. Lo spostamento dei tasselli consente di regolare le date ogni anno.

