This Answer Should Cover all of Written/Recorded, Human History
The MySQL acceptable range for dates is from 1000-01-01 to 9999-12-31. (Source: Dev.MySQL.com: 11.2.2 The DATE, DATETIME, and TIMESTAMP Types.) So, in fact, the problem doesn't begin with negative or BCE dates, but with all dates preceding the year 1000, for instance, the birth of Trajan, 53 AD, etc..
So, let's hijack some dates! We are going to treat the year 3000 as the year 1000. I know this has been suggested by others, but where's the code and the demonstration? That's what I want to fill in.
When subtracting/adding years to hijack date ranges, we need to handle some odd edge cases. For instance, both BC and AD (up to 9999 AD) are broken, but these two date ranges work differently. What kind of logic can do a successful remap with both of the follow requirements?
- In AD, we say, "This year is x, next year is x + 1."
- In BC, we say, "This year is x, next year is x - 1."
Anyway, let's code!
Convert From Any DB Value to Date
Birth of Laozi, formally "571 BCE", technically, "-571 AD". It stores as 4571
.
year = 4571;
if(year >= 3000) {
diff = year - 3000;
real_year_number = 1000 - diff;
console.log(real_year_number);
}
Convert From Any Date to DB Value
So, once again, birth of Laozi, "571 BCE". It is treating as -571
.
year = -571;
if(year < 1000) {
diff = ((year - 1000) * (-1)) + 3000;
console.log(diff);
}
Addendum -- About Dashes
If you're playing with this stuff, you'll soon realize that many date format libraries require only two dashes "year-month-day", etc., and using a negative, "-year-month-day", can just wreak havok. Personally, I have rewritten the above to have "BCE" prepended to bce dates, i.e., you'll have values like "bce571-01-01" instead of "-571-01-01", etc..