> DateTime is a class for the representation of date/time combinations, and is part of the Perl DateTime project.
> It represents the Gregorian calendar, extended backwards in time before its creation (in 1582). This is sometimes known as the "proleptic Gregorian calendar". In this calendar, the first day of the calendar (the epoch), is the first day of year 1, which corresponds to the date which was (incorrectly) believed to be the birth of Jesus Christ
Always RTFM.
Edit: I double-checked, and while this was not in the docs in the first release, it _was_ in the docs as of 2015.
But it is typically used when referring to events located in areas with no calendar system familiar to modern readers, most notably the Maya calendar. Maya Long Count dates are typically converted to the proleptic Gregorian calendar.
Also, many modern historical writings will display both Julian and Gregorian dates, particularly for dates around when the calendars were changing or when context is unclear (e.g. a historical figure who was born in an area with one calendar and died in an area with another calendar).
Fun fact: Greece was still using the old Julian calendar as of 1928, so it's entirely possible that you'll see dates on relatively recent Greek documents that are up to 14 days off from the calendar the rest of the world was using. Civil timekeeping is just a mess.
In science-related code, I can image a case for calculating things like seconds elapsed across a very long time period. But in that case you're not really dealing with dates. Instead, you want something like the Unix epoch, but probably with an earlier epoch start.
There may be some very niche cases for pre-1582 dates in code that I'm not thinking of. But I'd expect that in this case you're going to put a lot of effort into finding the right libraries, or you might just write your own code.
Regardless, the linked blog post says of DateTime: "Unfortunately, like Python, a proper error message for impossible Gregorian dates is notably absent."
But this is just wrong. There's no "proper error message" to emit. The code works as documented.
Lots of written work pre 1582 that needs to be accurately catalogued.
Source: I used to work on one of the first computerised library management software systems, and plenty of our academic customers had manuscripts dating back that far.
(p.s. autarch thanks for your efforts in open source).
People writing knowledge base software, like Wikidata. It's helpful to be able to display historical dates in any desired calendar, and also to be able to do date arithmetic between any two arbitrary dates.
On some level, it doesn't matter if an inscription corresponds to "August 31, 83 CE" or "September 2, 83 CE" (a date potentially inscribed at the site Takalik Abaj in Proleptic Gregorian or Julian), but it's nice to try to get the details correct. And if you want to correlate with other events in history (especially if you can find astronomical event data from Europe), you need to be at least consistent.
Plus, it's just fun to think about these events from long ago in terms (dates) we understand.
The afternotes at the end of the post are worth reading; people have sent me various qualifications and corrections over the years.
I find these things so much easier to think about if you consider the change as a change from one calendar system to another calendar system. Those 10 days certainly exist, in both calendar systems, they just represent different points in time. I.e., I think it's easier to just consider both calendar systems as the rules, extended forward & backwards infinitely ("proleptic"). Some people switched from a Julian calendar to a Gregorian one in 1582.
"Some people did not experience days with these labels in some areas of the world" … I get where it's coming from, but it's not how I'd build a library.
If you worry about the switch, then you have to ask "which switch?" which TFA only lightly touches on. The 1582 one is famous, of course, but not everyone switched, and other parts of the worlds switched as time went on, to as late as 1918, when Russia switched.[1] (And you can see other messiness in that table, too.)
Needing to deal with it is niche enough that I think most language std libs should implement the proleptic Gregorian calendar, and let an application whose niche requires it deal with the switch (& whichever switch it requires).
[1] https://en.wikipedia.org/wiki/List_of_adoption_dates_of_the_...
Not in the standard Gregorian calendar. Those dates only exist in the proleptic Gregorian calendar. The standard Gregorian calendar explicitly skips them. That's because you can't feasibly go back and change all the Julian dates that had been physically written down for centuries. That's why it's called the Gregorian "shift".
Thanks. I haven’t known that countries switched in different years.
Gregorian calendar is just one piece.
https://en.wikipedia.org/wiki/Civil_calendar
Eighteen countries use another calendar alongside the Gregorian calendar…
(OpenBSD)
$ man cal
[...]
The Gregorian Reformation is assumed to have occurred in
1752 after the 2nd of September. By this time, most
countries had recognized the Reformation (although a few
did not recognize it until the early 1900s). Eleven days
following that date were eliminated by the Reformation, so
the calendar for that month is a bit unusual.
(Ubuntu Linux) [...]
-s country_code
Assume the switch from Julian to Gregorian Calendar at
the date associated with the country_code. If not
specified, ncal tries to guess the switch date from the
local environment or falls back to September 2, 1752.
This was when Great Britain and her colonies switched
to the Gregorian Calendar.1582 is Catholic Europe
1700 or 1701 is Protestant Europe
1752 is Great Britain and its colonies which include USA
1918 is Russia
1923 Greece
https://en.wikipedia.org/wiki/Adoption_of_the_Gregorian_cale...
> In A.D. 1582 Pope Gregory XIII found that the existing Julian calendar insufficiently represented reality, and changed the rules about calculating leap years to account for this. Similarly, in A.D. 2013 Rockchip hardware engineers found that the new Gregorian calendar still contained flaws, and that the month of November should be counted up to 31 days instead.
Technically, they switched to the Revised Julian[0] calendar, not the Gregorian. Also, it was only some of the churches making up Eastern Orthodoxy that switched; others remain on the Julian calendar to this day, and all of them still use the Julian calendar to calculate the date of Pascha.
Such a flag day didn't involve removing days from one calendar or the other, it switched between them.
I wouldn't say it's it's straightforward to convert between them, either. The Gregorian calendar was first adopted in 1582, but the UK and it's colonies didn't follow suit until 1752. Russia didn't convert until 1918, and Greece didn't switch until 1923. We're just over 100 years out from active use of the Julian calendar. So you have to know who the speaker is and where they are or where they are from to know what they mean.
Since these places switched at different times, they had to skip a different number of days. It was 10 in the 16th century. It was 13 in the 20th!
If you're reading a journal by a British man who lived in Russia through the end of the Great War and then moved to Greece in 1920, what does he mean when he's talking about a lunar eclipse he just witnessed?
If you are talking about a historical event from Egypt in 500 BCE, you would say "this happened in 500 BCE", not "this happened in year 26 of the 27th dynasty".
The distinction is important in the context of doing historical research, but it is no more appropriate to write dates in secondary sources using the Julian calendar than it would be to try to explain Egyptian history by spouting hieroglyphics at people.
The Magna Carta was sealed on June 15, 1215 for the Julian calendar. But if you want the actual anniversary, it was sealed on June 22, 1215 using the proleptic Gregorian calendar. Do you want to know the date people remember, ir the date of the true anniversary?
The coronation of Henry VIII is listed almost everywhere you look as June 24, 1509. Except that's also Julian. The date of the Gregorian calendar is July 4, 1509.
We don't remember the proleptic dates. We remember the dates that were then in use.
And if you say you're just always going to use the contemporary recorded date, that's fine. Until you get to dates like February 29, 1700. What do you put in your system then?
1752 is late enough that Benjamin Franklin, George Washington, Thomas Jefferson and others were born before that change.
I think that’s the reason that programming languages tend to adopt the proleptic Gregorian calendar and leave it up to the programmer to figure out when the calendar was adopted in the countries they care about.
Except that countries apparently had to answer various questions when they adopted the Gregorian calendar, and they didn’t all chose the same answers. Ideally, we’d have something like tzdb but for calendar adoption. But I guess the need doesn’t come up all that often.
Look at https://en.wikipedia.org/wiki/New_Year#Annunciation_Style :
“Despite the unification of the Scottish and English royal crowns with the accession of King James VI and I in 1603, and even the union of the kingdoms themselves in 1707, England continued to use Annunciation Style while Scotland used Modern Style. This led to the act being recorded at the time in England as 6 March 1706 (rather than 1707), because in England (unlike Scotland) it fell before the new year began (on 25 March).”
It apparently caused trouble for travelers (from the New Style Calendar Act https://en.wikisource.org/wiki/Calendar_(New_Style)_Act_1750 ):
“WHEREAS the legal Supputation of the Year of our Lord in that Part of Great Britain called England, according to which the Year beginneth on the 25th Day of March, hath been found by Experience to be attended with divers Inconveniencies, not only as it differs from the Usage of neighbouring Nations, but also from the legal Method of Computation in that Part of Great Britain called Scotlond, and from the common Usage throughout the whole Kingdom, and thereby frequent Mistakes are occasioned in the Dates of Deeds, and other Writings, and Disputes arise therefrom.”
Although, I think “common usage” in that statement implies that it was common to just do what other countries did, except when filling out legal documents.
[1] https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar
In our Dip (in house db) client library, we built what we called a policy that auto selects partitions based on every crud operations. The policies can be specified once for each collection in collections.json based on fields or query.
So for policies where partition involves the date type fields, be it range or fixed dates, it was incredibly hard to generate universal date names from ranges.
The policy mechanism was finished fairly quickly as Dip is inherently distributed first. But reasoning about date names was so incredibly hard.
The missing dates mentioned in the article did come up during development adding to the woes.
But the upside now is that application code no longer worries about the distributed partitions. Policy handles that. Some sort of architecture as code. Don't know whether AAC is an existing term or whether we coined it.
And, frankly, there are other problems to deal with beyond correctly handling the Julian/Gregorian switch. In Nelson's Navy, for example, the new day started at noon rather than midnight as we'd expect. AM could be June 1st, PM could be June 2nd, and both could be Tuesday.
And then there are lots of historical events with dates like "on or about August 6th" or "mid-September" or the "in the Fall of".
Trying to deal with historical dates in what a programmer would consider a perfectly correct way is something of a fool's game.
https://en.wikipedia.org/wiki/List_of_non-standard_dates#Feb...
Tried using ncal like in the examples in that blog post, but it did not work correctly using either Julian or Gregorian. Of course the Swedish calendar from 1700-1712 was neither, but somewhere in-between, because of the (failed) attempt to gradually move from one to the other.
Meta: one can also link to this article, which redirects:
Instead of flipping the switch in the 1500s... or 1700s... they instead did a slow roll out until they finally flipped the switch and did a big leap.
https://www.americanscientist.org/article/date-distinctions
In “The Future of Time,” the authors state that “different countries and religions adopted the reforms [the Gregorian calendar] at different times and in different ways. In 1712 Sweden added a February 30 to its national calendar.” There was a February 30 in Sweden in 1712, but the context in which it is presented in the article is misleading. In 1700 the Swedes decided to switch from the Julian to the Gregorian calendar by eliminating leap-year days for 40 years. So 1700, which is a Julian leap year but not a Gregorian leap year, did not have a leap day. In both 1704 and 1708, through bureaucratic error, there were leap days. In 1712, the situation was resolved by switching back to the Julian calendar; this meant that the missing leap day that would have occurred in 1700 had to be added, and was, as February 30. It wasn’t until 1753 that the Swedes finally adopted the Gregorian calendar by making the date March 1 follow February 17.tl;dr - ActiveSupport::TimeWithZone used absolute seconds counting to determine dates while DateTime used a proper Gregorian calendar. This means dates before October 15, 1582 have different internal values when compared.
The behavior showed up because a test was using a DateTime value to set a MySQL DATETIME column to the DB minimum value, which is 1000-01-01 00:00:00, and then comparing the DB record attribute to the original variable used to set it.
Something like:
date = DateTime.new(1000, 1, 1, 0, 0, 0, 'UTC')
record.update(happened_at: date)
record.happened_at == date # => false
I "discovered" the missing Gregorian dates when I wrote a loop counting forward in time from Jan 1, 1000 until the corresponding TimeWithZone and DateTime records returned true when compared with ==.imo, if i am using Georgian i want that system even retroactively, just like projecting a date back into the stone age. I don't care that a particular geography or culture changed calendars.
So I suppose what is really going on is that some libraries are using Georgian consistently, and others are using some hybrid "civic" calendar that tracks what the romans and the catholics were using, so dates in history books make sense.
I’ll draft a Dubia so that when future popes change the calendar they will include a representative code sample and details about how we handle this.
(It’s important to remember that the pope and friends were operating much more like an international standards body than a religious leader when doing things like this.)
And if there is a contract dated to the 6th October 1582, that does raise questions about its legitimacy (though in general misdating a contract does not void it, it would merely be one point of evidence in your argument that it's a forgery, just like using a particular font in a modern printed contract)
It's one of those "well technically" things programmers love to obsess over and the judge just says "everyone knows what was meant, stop being an idiot."
Yeah there are a lot of examples of dates being written two ways on the same document/artifact. In the Anglosphere there are two changes that happened close together: the movement of the new year from Lady Day to the first of January, and the Julian/Gregorian calendar jump, so that confounds things slightly. https://en.wikipedia.org/wiki/Old_Style_and_New_Style_dates
'A date object represents a date (year, month and day) in an idealized calendar, the current Gregorian calendar indefinitely extended in both directions.'
'This matches the definition of the “proleptic Gregorian” calendar in Dershowitz and Reingold’s book Calendrical Calculations.'
https://docs.python.org/3/library/datetime.html#id2 https://docs.python.org/3/library/datetime.html#id5
Whereas Ruby has proleptic Gregorian Time, but civic DateTime:
https://ruby-doc.org/stdlib-2.6.1/libdoc/date/rdoc/DateTime....
Dates are a mapping from human-readable labels to instants in time; critically, this mapping is not a total function (there are dates that map to no instant in time in a particular calendar, such as October 5-14 1582 in the Gregorian calendar, or 2:30am March 8 2026 in US timezones due to DST), nor is it in fact a function at all depending on how you define your inputs (1:30am November 1 2026 in US timezones is ambiguous if you don't specify DST/ST).
Furthermore, the mappings (both for past dates and future dates!) can themselves change over time (changes to DST, timezones, and calendars such as in TFA), and you need to keep track of these changes in perpetuity, as well as at which instant in time they were implemented, and we don't necessarily have that information for some of these historical changes, we only have the date as written down, which itself can suffer from the ambiguity problem (is it the date pre- or post- calendar change?).
This makes dealing with past dates tricky, and dealing with future dates speculative at best. For instance, what's February 28th + 1 day? The answer depends on the calendar system and the year; we can answer it definitively for past years but not necessarily for future years (maybe in 2040 we'll move the leap day to December 32nd). This is why it's important to immediately convert past dates (and sometimes future dates, depending on the use case) to unambiguous instants in time, and only convert them back to dates for display purposes.
"Wednesday, August 12th 2026" and "8 days from now" are also semantically distinct for some purposes: if have 8 doses of a daily prescription left, I'm still going to run out in 8 days even if tomorrow the government decides to repeal the Gregorian calendar, thus changing the name of "8 days from now" from "Wednesday, August 12th 2026" to "Sunday, August 2nd 2026". My medication doesn't care what the government decides to call 8 days from now, I'm going to run out either way. The pharmacy, on the other hand, very much does care what the government decides to call 8 days from now, because perhaps they're closed on Sundays. The calendar change means that "8 days from now" went from being not-a-Sunday to a Sunday, affecting their operating hours.
It's really just another instance of one of the two hard problems in computer science: naming things.
It would natively display "Future" if the file timestamp was ahead of the system clock, but you could also add dates. I remember seeing directory listings like
xyzzy.foo 49152 ----rw-d Christmas 1988