Passa al contenuto principale

Appendix B. Giorno della settimana

Questa appendice mostra come calcolare il giorno della settimana da qualsiasi data del calendario gregoriano. Questo è importante per comprendere perché RFC 3339 non include informazioni sul giorno della settimana—perché può essere calcolato con precisione.

Congruenza di Zeller

Un algoritmo comunemente utilizzato per calcolare il giorno della settimana è la congruenza di Zeller, inventata da Christian Zeller nel 1882.

Formula

h = (q + ⌊13(m+1)/5⌋ + K + ⌊K/4⌋ + ⌊J/4⌋ - 2J) mod 7

Dove:

  • h: Giorno della settimana (0 = sabato, 1 = domenica, 2 = lunedì, ..., 6 = venerdì)
  • q: Giorno del mese (1-31)
  • m: Mese (3-14, dove 3 = marzo, 4 = aprile, ..., 12 = dicembre, 13 = gennaio, 14 = febbraio)
  • K: Anno del secolo (year % 100)
  • J: Secolo (⌊year/100⌋)
  • ⌊x⌋: Funzione pavimento

Nota: Gennaio e febbraio sono trattati come il 13° e 14° mese dell'anno precedente.

Implementazione Python

def day_of_week_zeller(year, month, day):
"""
Calcolare il giorno della settimana usando la formula di Zeller
Restituisce: 0=sabato, 1=domenica, ..., 6=venerdì
"""
# Gennaio e febbraio sono trattati come mesi 13 e 14 dell'anno precedente
if month < 3:
month += 12
year -= 1

q = day
m = month
K = year % 100
J = year // 100

h = (q + (13 * (m + 1)) // 5 + K + K // 4 + J // 4 - 2 * J) % 7

# Convertire al formato comune: 0=lunedì, ..., 6=domenica
# Zeller: 0=Sab, 1=Dom, 2=Lun, 3=Mar, 4=Mer, 5=Gio, 6=Ven
# Aggiustare a: 0=Lun, 1=Mar, 2=Mer, 3=Gio, 4=Ven, 5=Sab, 6=Dom
return (h + 5) % 7

def day_name(year, month, day):
"""Restituire il nome del giorno della settimana"""
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday']
return days[day_of_week_zeller(year, month, day)]

# Esempi
print(day_name(2002, 7, 15)) # Monday
print(day_name(2000, 1, 1)) # Saturday
print(day_name(1999, 12, 31)) # Friday

Algoritmo più semplice

Per le implementazioni di programmazione, può essere utilizzato un algoritmo più intuitivo:

def day_of_week_simple(year, month, day):
"""
Calcolo semplificato del giorno della settimana
Restituisce: 0=lunedì, ..., 6=domenica
"""
# Giorni cumulativi prima di ogni mese (anno non bisestile)
t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]

if month < 3:
year -= 1

y = year % 100
c = year // 100

return (y + y // 4 + c // 4 - 2 * c + t[month - 1] + day) % 7

Implementazione JavaScript

function dayOfWeek(year, month, day) {
// L'oggetto Date di JavaScript calcola automaticamente il giorno della settimana
const date = new Date(year, month - 1, day);
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'];
return days[date.getDay()];
}

// Esempi
console.log(dayOfWeek(2002, 7, 15)); // Monday

Esempi di verifica

DataGiorno della settimanaVerificato
2002-07-15Lunedì (Monday)
2000-01-01Sabato (Saturday)
1999-12-31Venerdì (Friday)
1985-04-12Venerdì (Friday)
1990-12-31Lunedì (Monday)

Perché RFC 3339 non include il giorno della settimana

1. Informazione ridondante

Il giorno della settimana può essere calcolato con precisione dalla data, quindi includerlo introduce potenziali incoerenze:

Esempio errato:
"Monday, 2002-07-16T10:00:00Z"

Problema: 2002-07-16 è in realtà martedì, non lunedì
A quale si dovrebbe dare fiducia? Giorno della settimana o data?

2. Complessità aumentata

I parser devono gestire la validazione e le incoerenze tra giorno della settimana e data.

3. Problemi di localizzazione

I nomi dei giorni della settimana differiscono tra le lingue:

Inglese: Monday, Tuesday, Wednesday, ...
Francese: Lundi, Mardi, Mercredi, ...
Italiano: Lunedì, Martedì, Mercoledì, ...

4. Non influisce sul punto temporale

Il giorno della settimana non influisce sulla determinazione del punto temporale, è solo per la leggibilità umana.

Raccomandazione

Se è necessario visualizzare il giorno della settimana:

from datetime import datetime

# Analizzare il timestamp RFC 3339
timestamp = "2002-07-15T10:00:00Z"
dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))

# Calcolare e visualizzare il giorno della settimana
day_name = dt.strftime('%A')
print(f"{timestamp} is a {day_name}")
# Output: 2002-07-15T10:00:00Z is a Monday

Conclusione: Poiché il giorno della settimana può essere calcolato in modo preciso e deterministico dalla data, includerlo nel formato del timestamp non è solo non necessario ma dannoso.