BC date support

Scientists, genealogists, and other researchers often work with events in the distant past, and need tools to record and work with dates before the common era. For example, PostgreSQL can support dates from 4713 BC to 294276 AD.

It seems that CPython date is limited to the MINYEAR of 1. This limits projects, such as Django, since non-CE date handling cannot be built without turning to a contributed library like Astropy.

How can Python core be extended to support a wider range of dates?


Python dates have properties that PostgreSQL apparently doesn’t support – you can subtract them to get a timedelta, and you can add a timedelta to a date (or subtract a timedelta from a date) to get another date. This doesn’t really work for dates outside the current Gregorian calendar, and MINYEAR=1 is a vast oversimplification. There’s a comment at the top of datetime.py referencing the “proleptic Gregorian” that’s key here.

There are other problems with trying to extend the date range, e.g. there’s no “year zero”, and AFAIK the months historically didn’t always have the number of days they have in the Gregorian calendar (and what about leap years?). I believe I learned in high school that the Romans celebrated new year’s day on a different date (wasn’t March the first month of the year?), so the years don’t even overlap.

All this (and other reasons like implementation constraints) mean that for representing non-Gregorian dates you’re better off inventing your own system (e.g. a string or a tuple of three integers) than trying to shoehorn these into the datetime type.

The original author of datetime, @tim.one, will certainly correct me with even more facts and reasons why this wouldn’t be a good idea.

I think most of the issues you mention don’t arise if you stick to the proleptic Gregorian as your coordinate system, like datetime and postgres do? Of course you have to deal with them as soon as you want to convert between proleptic Gregorian and other coordinate systems, like those used in historical texts, but that’s out-of-scope for datetime.

The lack of year zero definitely creates complications, and I don’t know if it’s worth dealing with them – it’s not something that interests me personally. But I’m pretty sure the calculations for BCE dates are at least well-defined and that we could support them if someone did the work and the maintainers were willing to support it.

1 Like

@brylie this sounds like a perfect use-case for domain-specific third-party libraries.


Which Roman calendar? There were multiple Roman calendars and calendar reforms. :slight_smile: You are right, the first Roman calendar used to start in March and just had 10 months. December was the 10th months.

If you just need to address days and Newtonian physics is good enough, then I recommend to use Julian Day Number. JDN is commonly used by astronomers to refer to dates over the last six thousand years. It’s well defined and days can be easily mapped to Julian and Gregorian calendar. JDN is also simpler to work with because you only need an integer for days and integer/float for seconds to refer to time stamps accurately. JDN starts on noon Jan 1st 4713 BC (mnemonic: 1 + 1+ 4711 Eau de Cologne) in proleptic Julian calendar. The date was chosen because it’s the start of a solar cycle and metonic lunar cycle.