Почему две даты MySQL в 1582 кажутся одинаковыми, но результат сравнения равен false?
Я знаю, что григорианский календарь начался 15 октября 1582 года, а во время перехода от юлианского календаря 10 дней были отброшены.
Когда я делаю этот запрос:
SELECT STR_TO_DATE('1582-10-05', '%Y-%m-%d')
Я получаю этот результат:
1582-10-15 (the 10 days difference).
Но когда я пытаюсь сопоставить такие даты, я получаю исходную дату (5 октября, а не 15).
Например:
SELECT STR_TO_DATE('1582-10-05', '%Y-%m-%d') = STR_TO_DATE('1582-10-15', '%Y-%m-%d')
Я получаю ложный ответ, хотя вы ожидали получить истинное значение с 5 октября, фактически считая 15 октября, как мы видели в первом примере.
Кто-нибудь может объяснить, что здесь происходит?
Ответы
Ответ 1
В документации указано, что функции TO_DAYS
и FROM_DAYS
должны быть вызваны осторожно из-за того, что вы заметили преобразование. Кроме того, когда я проверяю исходные коды MySQL, я понял, что STR_TO_DATE
использует подобную методологию с этими функциями. Насколько я понимаю, даты переноса полностью небезопасны для хранения или применения операций. Документация говорит; "Dates during a cutover are nonexistent."
тоже.
Также для несоответствия между разными серверами у меня может быть объяснение. У меня есть две разные машины, в которых MySQL установлен в Стамбуле, Турции и Франкфурте, Германия. У них одинаковая настройка , исключая настройки локализации. Первый показывает 1, другой показывает 11 для запроса на дату. Это означает (по моему скромному мнению) есть необъяснимые разделы о переделке и локализации календаря в официальной документации.
Ответ 2
Пожалуйста, просмотрите следующие результаты:
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.
Это указывает на то, что проблема заключается в том, как отображается дата 1582-10-05
, а не как она хранится. Результат № 2 показывает, что если вместо DATE_FORMAT
вместо явного преобразования даты в тот же строковый формат, то отображается дата ввода, Это также объясняет, почему запрос сравнения в вопросе возвращает false: за кулисами две сохраненные даты различаются.
Как вы обнаружили, этот причуд встречается для всех дат между 1582-10-05
и 1582-10-14
включительно, т.е. диапазон дат, которые не действительно существуют: неявное преобразование в текст для всех из них дает дату через 10 дней. Поэтому, если по какой-то причине необходимо отображать даты в этом диапазоне (возможно, сомнительно), простым обходным путем является всегда использовать функцию DATE_FORMAT
.