Dates That Don't Exist (2015)
Dates That Don't Exist (2015)
Originally posted on ENOSUCHBLOG — a space for programming, philosophy, and pedaling.
The Mystery of the Vanishing Days
In the year 1582, the Catholic world underwent a significant chronological shift. Under the authority of the papal bull inter gravissimas, the Julian Calendar was abandoned in favor of the Gregorian Calendar.
The primary motivation was precision. The Gregorian system adjusted the average length of a year from days down to days—a tiny modification of approximately .
The Logic of Leap Years
This adjustment birthed the leap year rules we use today:
- A year is a leap year if it is divisible by 4.
- However, if it is divisible by 100, it is not a leap year...
- Unless it is also divisible by 400.
| Year | Divisible by 4? | Divisible by 100? | Divisible by 400? | Leap Year? |
|---|---|---|---|---|
| 1900 | Yes | Yes | No | No |
| 1904 | Yes | No | No | Yes |
| 2000 | Yes | Yes | Yes | Yes |
The Great Correction
Because the Julian calendar was slightly off, it had "drifted" over the centuries. By 1582, it was lagging eleven days behind the solar reality. To synchronize the calendar, ten days had to be deleted from the year 1582.
It took nearly two decades of deliberation—largely because the Church wanted to avoid erasing holidays and specifically wanted to fix the drift of Easter—but they eventually settled on a specific window.
On October 4, 1582, people in Catholic regions went to bed; they woke up ten days later on October 15, 1582.
Essentially, the following dates October 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 simply do not exist in the Gregorian system.
How Do Programming Languages Handle This?
If these dates are mathematically and historically "impossible" in the Gregorian system, do our coding tools recognize that?
💎 Ruby
Ruby handles this with impressive accuracy. It refuses to instantiate a DateTime object for a non-existent Gregorian date.
require 'date'
# Attempting to create October 5, 1582
DateTime.new(1582, 10, 5)
# Result: ArgumentError: invalid date
This strictness is found in the underlying C code (ext/date/date_core.c), specifically within the datetime_s_civil function:
if (!valid_gregorian_p(y, m, d, nth, ry, rm, rd)) rb_raise(rb_eArgError, "invalid date");
🐍 Python
Python's datetime module claims to use the "current Gregorian calendar," but it fails to enforce the 1582 gap.
from datetime import date
# October 5, 1582
d = date(1582, 10, 5)
print(d) # Output: 1582-10-05
This behavior is consistent across both Python 2 and Python 3.
🐪 Perl
Since Perl lacks a built-in equivalent to the above, I tested the popular DateTime module from CPAN. Like Python, it ignores the historical gap.
#!/usr/bin/env perl
use DateTime;
my $dt = DateTime->new( year => 1582, month => 10, day => 5 );
print $dt->ymd('/'), "\n";
# Output: 1582/10/5 (No error thrown)
Summary of Correctness
- Ruby: Correctly identifies the gap.
- Python: Allows impossible dates.
- Perl (DateTime): Allows impossible dates.
Final Thoughts
While this isn't a catastrophic failure like the Y2K bug or the Unix epoch rollover, it highlights the nuance required for true "correctness" in software. Even a 10-day window from half a millennium ago matters if you are striving for absolute precision.
For those interested in the math, I recommend researching Zeller’s Congruence or Pre-Julian Calendars.
— William
Afternotes: The Global Struggle
Not everyone followed the Pope. Protestant nations and other religions resisted the papal bull. Many Protestant churches stayed with the Julian system into the 1700s, and the Eastern Orthodox church didn't switch until 1929. Each of these transitions required their own unique "date deletions" to catch up.
The ncal utility handles this more gracefully than the languages above. By using the -s flag with a country code, it determines when that specific nation transitioned.
Example: Italy
ncal -s IT 10 1582
(Shows the jump from Oct 4 to Oct 15)
Example: Great Britain
ncal -s GB 9 1752
(Shows the jump in September 1752)
Addendum (2026-06-30): A note from John Costello mentions that even ncal(1) isn't perfect, as it overlooks the unique calendar shifts Sweden experienced during the 1700s.