Appendix B. Wochentag
Dieser Anhang zeigt, wie man den Wochentag aus jedem gregorianischen Kalenderdatum berechnet. Dies ist wichtig, um zu verstehen, warum RFC 3339 keine Wochentagsinformationen enthält—weil sie präzise berechnet werden können.
Zellers Kongruenz
Ein häufig verwendeter Algorithmus zur Berechnung des Wochentags ist Zellers Kongruenz, erfunden von Christian Zeller im Jahr 1882.
Formel
h = (q + ⌊13(m+1)/5⌋ + K + ⌊K/4⌋ + ⌊J/4⌋ - 2J) mod 7
Wobei:
h: Wochentag (0 = Samstag, 1 = Sonntag, 2 = Montag, ..., 6 = Freitag)q: Tag des Monats (1-31)m: Monat (3-14, wobei 3 = März, 4 = April, ..., 12 = Dezember, 13 = Januar, 14 = Februar)K: Jahr des Jahrhunderts (year % 100)J: Jahrhundert (⌊year/100⌋)⌊x⌋: Abrundungsfunktion
Hinweis: Januar und Februar werden als 13. und 14. Monat des Vorjahres behandelt.
Python-Implementierung
def day_of_week_zeller(year, month, day):
"""
Wochentag mit Zellers Formel berechnen
Gibt zurück: 0=Samstag, 1=Sonntag, ..., 6=Freitag
"""
# Januar und Februar werden als Monate 13 und 14 des Vorjahres behandelt
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
# In gängiges Format konvertieren: 0=Montag, ..., 6=Sonntag
# Zeller: 0=Sa, 1=So, 2=Mo, 3=Di, 4=Mi, 5=Do, 6=Fr
# Anpassen auf: 0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So
return (h + 5) % 7
def day_name(year, month, day):
"""Namen des Wochentags zurückgeben"""
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday']
return days[day_of_week_zeller(year, month, day)]
# Beispiele
print(day_name(2002, 7, 15)) # Monday
print(day_name(2000, 1, 1)) # Saturday
print(day_name(1999, 12, 31)) # Friday
Einfacherer Algorithmus
Für Programmierimplementierungen kann ein intuitiverer Algorithmus verwendet werden:
def day_of_week_simple(year, month, day):
"""
Vereinfachte Wochentagsberechnung
Gibt zurück: 0=Montag, ..., 6=Sonntag
"""
# Kumulative Tage vor jedem Monat (kein Schaltjahr)
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
JavaScript-Implementierung
function dayOfWeek(year, month, day) {
// JavaScript Date-Objekt berechnet automatisch den Wochentag
const date = new Date(year, month - 1, day);
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'];
return days[date.getDay()];
}
// Beispiele
console.log(dayOfWeek(2002, 7, 15)); // Monday
Überprüfungsbeispiele
| Datum | Wochentag | Verifiziert |
|---|---|---|
| 2002-07-15 | Montag (Monday) | ✅ |
| 2000-01-01 | Samstag (Saturday) | ✅ |
| 1999-12-31 | Freitag (Friday) | ✅ |
| 1985-04-12 | Freitag (Friday) | ✅ |
| 1990-12-31 | Montag (Monday) | ✅ |
Warum RFC 3339 keinen Wochentag enthält
1. Redundante Information
Der Wochentag kann präzise aus dem Datum berechnet werden, daher führt seine Aufnahme zu potenziellen Inkonsistenzen:
Falsches Beispiel:
"Monday, 2002-07-16T10:00:00Z"
Problem: 2002-07-16 ist tatsächlich Dienstag, nicht Montag
Welchem sollte vertraut werden? Wochentag oder Datum?
2. Erhöhte Komplexität
Parser müssen Validierung und Inkonsistenzen zwischen Wochentag und Datum behandeln.
3. Lokalisierungsprobleme
Wochentagsnamen unterscheiden sich zwischen Sprachen:
Englisch: Monday, Tuesday, Wednesday, ...
Französisch: Lundi, Mardi, Mercredi, ...
Deutsch: Montag, Dienstag, Mittwoch, ...
4. Beeinflusst Zeitpunkt nicht
Der Wochentag beeinflusst die Bestimmung des Zeitpunkts nicht, er dient nur der menschlichen Lesbarkeit.
Empfehlung
Wenn Sie den Wochentag anzeigen müssen:
from datetime import datetime
# RFC 3339-Zeitstempel parsen
timestamp = "2002-07-15T10:00:00Z"
dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
# Wochentag berechnen und anzeigen
day_name = dt.strftime('%A')
print(f"{timestamp} is a {day_name}")
# Ausgabe: 2002-07-15T10:00:00Z is a Monday
Fazit: Da der Wochentag präzise und deterministisch aus dem Datum berechnet werden kann, ist seine Aufnahme in das Zeitstempelformat nicht nur unnötig, sondern schädlich.