Einleitung

Es ist Donnerstagmorgen, 8 Uhr. Du sitzt vorm Monitor, das leere Red‑Bull neben der Tastatur, und sollst gerade eine raffinierte Java‑Logik in T‑SQL nachbauen. Kaum hast du deine Funktion deployed, zeigt das Ergebnis für heute plötzlich 739 251 statt 739 253 an – und dein innerer Schweinehund flüstert: „Oh Mann, hast du dich verschätzt?“ Verunsichert greifst du zur Python‑Shell, tippst dieselbe Rechnung ein, und siehe da: Auch Python spuckt 739 251 aus. Zwei verlorene Tage scheinen wie vom Erdboden verschluckt – willkommen im epischen Showdown: Java vs. Python & SQL, oder die große Suche nach zwei verlorenen Tagen!

Die verlorenen zwei Tage

Alles begann harmlos bei einem unschuldigen Kalender-Berechnungs-Experiment. In Python und T‑SQL klingt der Code so simpel:

from datetime import date
delta = date(2025,1,1) - date(1,1,1)
print(delta.days) # → 739251
SELECT DATEDIFF(DAY, '0001-01-01', '2025-01-01');  
-- → 739251

Aber wenn man in Java die gleiche Rechnung mit GregorianCalendar anstellt, schnurrt das Programm plötzlich 739 253 zurück! Wo sind die beiden Tage hin? Haben sie sich heimlich mit den Schaltsekunden verbündet? Nein – sie tummeln sich in den Untiefen historischer Kalender-Reformen.


Die Verschwörung der Kalender

Java liebt Geschichte: Es rechnet mit dem echten, knackigen Julianisch‑Gregorianischen Cutover am 15. Oktober 1582. Dort wurden damals einfach zehn Tage übersprungen (5. → 15. Oktober). Außerdem zählt der Julianische Kalender alle hundert Jahre als Schaltjahr – der Gregorianische überspringt die, die nicht durch 400 teilbar sind.

KalenderphaseSchalttage bis 1582Reformer übersprungenNettodifferenz
Julianisch (bis 1582) 338 –+12
Gregorianisch (ab 1582) – 10–10
Historische JVM‑Rechnung+2

Java rechnet historisch korrekt, während Python und SQL lieber konsequent im proleptischen Gregorianischen(-Modus) rechnen – völlig ohne historische Umwege.


Die Python‑Sekte

Python-Entwickler sind pragmatisch: Ein Datum ist ein Datum ist ein Datum. Ob Jahr 100 oder 1582 – der gregorianische Kalender gilt überall, jede Periode, jede Stunde. Kein unnötiges Herumhacken an vergessenen Tagen.

“Keep it simple, stupid”
– Pythons inoffizielles Motto

Das Ergebnis? 739 251 treue Tage, ohne Wenn und Aber.


SQLs nüchterne Wahrheit

SQL Server folgt dem gleichen Prinzip: DATEDIFF zählt Mitternachtsgrenzen und ignoriert historische Kapriolen. Das ist ideal für Business-Reports und Finanzanalysen, bei denen man weder im Jahr 1582 noch in der Maya-Apokalypse nachschlagen will.

-- Ergebnis: 739251
SELECT DATEDIFF(DAY, '0001-01-01', '2025-01-01');

Java’s Historienliebe

Java hingegen ist ein kleiner Geschichtsfreak. Der Standard-GregorianCalendar erzählt dir nicht nur, wie spät es ist, sondern auch, wie die Menschen damals zwischen 1582 und 1752 in Europa die Tage zählten. Nostalgie pur – oder ein Bug, je nach Perspektive.

GregorianCalendar cal = new GregorianCalendar();
cal.set(2025, Calendar.JANUARY, 1);
long days = (cal.getTimeInMillis() - new GregorianCalendar(1,0,1).getTimeInMillis())
/ (24L*60*60*1000);
System.out.println(days); // → 739253

Der Pro-Tipp

Wenn du proleptisch‑gregorianisch bleiben willst, setzt du das Cutover-Datum auf den frühesten Punkt:

cal.setGregorianChange(new Date(Long.MIN_VALUE));

Fazit: Zwei Welten, ein Datum

Am Ende des Tages (bzw. nach genau 739 251 oder 739 253 Tagen) steht die Erkenntnis:

  • Python & SQL sind pragmatische Pragmatiker.
  • Java ist der Historiker unter den Programmiersprachen.

Beide haben ihre Daseinsberechtigung – und beide liefern dir unterschiedliche Ergebnisse, wenn du tiefer in die Geschichte des Kalenders abtauchst. Wichtig ist nur, dass du weißt, auf welcher Seite deines Projekts du stehen willst: mit den 739 251 glasklaren Tagen oder den 739 253 historischen Anekdoten.

Also schnapp dir dein Lieblings-IDE, wähl deine(!) Zwei-Tages-Differenz und reise sicher durch die Zeit – egal ob du dabei in Python, SQL oder Java unterwegs bist!

weiterführende Links

Oracle JavaDoc – GregorianCalendar#setGregorianChange(Date)
Beschreibung der Methode, mit der Java den historischen Julian‑>Gregorian‑Cutover (15. Oktober 1582) steuert.

Python-Dokumentation – datetime.date
Erläuterung, dass Python das proleptische Gregorianische Kalendersystem „indefinitely extended“ nutzt (Jahr 1 als Tag 1).

Microsoft Docs – DATEDIFF (Transact-SQL)
Details zur Funktionsweise von DATEDIFF, das ausschließlich die Anzahl der überschrittenen Tagesgrenzen zählt.

Wikipedia – Julianischer Kalender
Überblick über das Julianische Kalendersystem mit Schaltjahrregeln (alle 4 Jahre) und historischen Abweichungen.

Wikipedia – Proleptischer Gregorianischer Kalender
Erklärung, wie der Gregorianische Kalender vor 1582 durchgehend angewendet wird (z. B. in Python, PostgreSQL, MySQL).

Wired – “Oct. 8, 1582: Nothing Happens … in Catholic Lands”
Populärwissenschaftlicher Artikel zur Einführung des Gregorianischen Kalenders und dem Überspringen von 10 Tagen im Oktober 1582.