I know that Gregorian calendar started on Oct 15th 1582, and during the transition from Julian calendar, 10 days had been dropped.
When I'm doing this query:
SELECT STR_TO_DATE('1582-10-05', '%Y-%m-%d')
I'm getting this result:
1582-10-15 (the 10 days difference).
But when I'm trying to match between such dates I'm getting the original date (Oct 5th and not 15th).
For example:
SELECT STR_TO_DATE('1582-10-05', '%Y-%m-%d') = STR_TO_DATE('1582-10-15', '%Y-%m-%d')
I'm getting a false response, although you would have expected to get a true since Oct 5th actually count as Oct 15th, as we saw in the first example.
Anyone can explain what's going on here?
On documentation it is stated that, TO_DAYS
and FROM_DAYS
functions must be called cautiously because of the transformation you noticed. Additionally, when I inspect the source codes of MySQL, I realized that STR_TO_DATE
uses similar methodology with these functions. As I understand, cutover dates are completely unsafe to store or apply operations. Documentation says; "Dates during a cutover are nonexistent."
, too.
Also for the inconsistency between different servers I may have an explanation. I have 2 different machines which have MySQL installed in Istanbul, Turkey and Frankfurt, Germany. They have same setup excluding localisation settings. First one shows 1, the other one shows 11 for the date substraction query. It means (in my humble opinion) there is unexplained sections about calendar cutover & localisation on official documentation.
Please see the following results:
SELECT STR_TO_DATE('1582-10-05', '%Y-%m-%d');
# Result #1: 1582-10-15
SELECT DATE_FORMAT(STR_TO_DATE('1582-10-05', '%Y-%m-%d'), '%Y-%m-%d');
# Result #2: 1582-10-05
SELECT DATE_FORMAT(STR_TO_DATE('1582-10-15', '%Y-%m-%d'), '%Y-%m-%d');
# Result #3: 1582-10-15
SQL fiddle demo.
These indicate the problem lies in the way the 1582-10-05
date is displayed rather than how it is stored. Result #2 shows that if the DATE_FORMAT
function is used instead to explicitly convert the date into the same string format then the input date is displayed. This also explains why the comparison query in the question returns false: Behind the scenes, the two stored dates are different.
As you've discovered, this quirk occurs for all dates between 1582-10-05
and 1582-10-14
inclusive, i.e. the range of dates that don't really exist: The implicit conversion to text for all of these gives a date 10 days after. So if for some reason there is a need to display dates in this range (perhaps questionable), a simple workaround is to always use the DATE_FORMAT
function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With