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
| Data | Giorno della settimana | Verificato |
|---|---|---|
| 2002-07-15 | Lunedì (Monday) | ✅ |
| 2000-01-01 | Sabato (Saturday) | ✅ |
| 1999-12-31 | Venerdì (Friday) | ✅ |
| 1985-04-12 | Venerdì (Friday) | ✅ |
| 1990-12-31 | Lunedì (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.