Подтвердить что ты не робот

Почему две даты 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 октября, как мы видели в первом примере.

Кто-нибудь может объяснить, что здесь происходит?

4b9b3361

Ответ 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.