Time is simple and well understood, right? Well, in a physical sense, it’s fairly well understood, but not at all simple. Cutting edge research into atomic clock technology promises an uncertainty of about a second over an interval of several billion years. This is plenty accurate enough to expose the minuscule relativistic effects of simply repositioning the clock. In fairly short order, differences of fractions of a picosecond can be detected, caused by the fact that time passes at imperceptibly different speeds depending on motion and the small changes in the local gravity field.
But the topic of these posts is the political vagaries of time, not the physical. The basic concept of time (modulo relativity) is something intuitively understood by almost all human beings, and human cultures have been accurately counting the days for thousands of years. So if understanding fractions of a picosecond is difficult, at least dates should be easy, right?
Unfortunately, not so much. Although the Western Calendar has become the de facto and de jure standard over most the world, mapping a Western date to a precise day has some complicated and even ambiguous edge cases.
Julius Caesar introduced the Julian Calendar to the Roman Republic around January 1, 45 BC, in part to help resolve some political problems created by the ancient Roman Calendar. A bit over a year later, on March 15, 44 BC, Julius Caesar was assassinated, motivated in part by some of the political problems the older calendar contributed to.
One might ask, exactly how many days have passed since Caesar was assassinated until the time you are reading this? Certainly, if this question can be answered correctly, arriving at the answer is a bit more subtle than most people realize.
The Julian Calendar was essentially version 1.0 of the Western Calendar, and it’s initial deployment had a few teething problems. There was a bit of confusion surrounding what it meant to have a leap day "every fourth year", and as a result leap days occurred every third year until the error was noticed and corrected by Augustus Caesar and his advisers nearly 40 years later. All leap years were suspended for 12 years, to be resumed at the proper interval once the error was corrected.
We don’t know exactly when those earliest leap years occurred. It does seem as though there is a single probable answer in the case of Caesar’s assassination, as both of the unfalsified candidate solutions for the early leap years lead to the same answer. However, there are many dates over the subsequent decades that could easily refer to one of two days. In any case, sometime around 1 BC to 4 AD, the Julian calendar stabilized, and for nearly 1600 years afterwards, there is an unambiguous mapping of historical dates to days.
However, the average length of a Julian year was longer than the length of the solar year. Over the next 1500 years the dates on the Julian Calendar drifted noticeably out of sync with the solar year, with the spring equinox (as determined by actual astronomical observations) coming some 10 days too early.
In February 1582, Pope Gregory XIII instituted the Gregorian Calendar. Leap years would come every fourth year, as before, but now leap years would be skipped every 100 years, except every 400 years. Also, the new calendar would skip 10 days in order to bring it back in sync with the solar year, with 1582-10-04 followed by 1582-10-15.
And, if that was the entire story, it wouldn’t be so bad, but unfortunately this reform ushered in several hundred years of ambiguity and confusion due to its uneven adoption. This reform was immediately adopted by the Catholic Church, the Papal States and many Catholic nations, with other Catholic nations moving to the Gregorian Calendar soon afterwards. However, the Gregorian Calendar was resisted by most Protestant and Orthodox nations. For example, Great Britain and her colonies held out until 1752,1 and Russia and Greece held out until 1918 and 1923 respectively, shortly after armed revolutions forced a change of government in those countries.
Then you have the case of the Swedish Calendar, which is notable for it’s particularly convoluted, mishandled, and then aborted transition from the Julian to the Gregorian calendars which resulted in a February 30, 1712. Also, in a few locales, including Switzerland and the Czech Republic, some people were using the Julian calendar at the same time others were using the Gregorian calendar.
Thus, accurately identifying a date after 1582 coming from original sources, or any historical date coming from modern sources, can be complicated or even impossible, depending on the precise context (or lack thereof) surrounding the date and its source.
Most dates in modern history books remain as they were originally observed, but there are a few exceptions. For example, the date of George Washington’s birth is observed as 1732-02-22 (Gregorian), even though the American colonies were using the Julian calendar at the time. On the day that Washington was born, the date was actually 1732-02-11 (Julian).
As encouraged by the ISO 8601:2004 standard, computer software often uses the proleptic Gregorian calendar for historical dates, extending the Gregorian calendar backwards in time before its introduction and using it for all date calculations. This includes PostgreSQL’s built-in time types. Glasgow Haskell’s time package supports both the proleptic Julian and Gregorian calendars, though defaults to the Gregorian Calendar.
The good news is that as time marched on, things have gotten better. Driven largely by faster methods of communication and transportation, we’ve gone from the typical context-dependence of dates down to the typical context-dependence of a dozen seconds or so. Even ignoring context, we are often more limited by the accuracy of a typical clock, and technologies such as GPS and NTP are often available to help keep them in reasonable agreement with atomic time standards.
In the upcoming posts of this two or three part series, we’ll look at the process of reducing this ambiguity, as well as local time, time zones, and how PostgreSQL’s nearly universally misunderstood
timestamp with time zone type actually works.