Лучший способ обработки дат до 1000 года нашей эры в MySQL?

9

Я создаю базу данных для записей, которые расширяются до 1000 года нашей эры, но поля MySQL Date и DateTime поддерживают только даты, начинающиеся с 1000.

Есть ли способ, который был бы более удобен, чем использование типа bigint для подсчета секунд до / после 01.01.1970 с использованием метки времени Unix, или переключение на программное обеспечение базы данных, которое поддерживает большие диапазоны дат?

Дэвид Лебауэр
источник
1
Ответ на
@stanleykylee спасибо за указание на это. Вопрос был другим, но проблема возникла в комментариях, и впоследствии на нее был дан ответ «выберите опорную дату и используйте числовое поле» с оговоркой «было бы утомительно кодировать, но довольно просто». и мой вопрос, среди прочего, спрашивает, является ли это лучшей альтернативой.
Дэвид Лебауэр
Ах, я как-то пропустил это в вопросе. Позвольте мне
посмотреть в лицо

Ответы:

7

Альтернативой является сохранение каждой части даты в числовом поле. Таким образом, у вас будет три поля:

year  SMALLINT     # Store positive values for AD and negative for BC years.
month TINYINT
day   TINYINT

Таким образом, он все еще будет читаемым человеком. Диапазон значений для различных числовых типов данных в MySQL доступен в разделе Обзор числовых типов . Требования к хранению доступны в разделе Требования к типу данных .

dabest1
источник
1
Я хотел бы дать этому +1, но я почти уверен, что логика дат будет ужасной, верно?
Камило Мартин
Как насчет одного поля, где мы храним даты в числовом формате, например, 2015-10-12 10:12:05
atpatil11
8

Для приложений, которым требуются очень старые (и для некоторых, даже в отдаленном будущем) даты, никакой тип данных даты в СУБД не подходит.

Если бы я был вами, я бы использовал строковый тип для собственного хранилища и придерживался бы значимого формата, такого как: + YYYY-MM-DD, чтобы приспособить BC / AD и любую прогнозируемую историческую или разумную будущую дату.

Если это может помочь, вы можете создать класс библиотеки, который преобразует ваш внутренний формат хранения в более презентабельный для уровня пользовательского интерфейса. Вы можете даже включить библиотечные функции, которые конвертируют в собственный тип даты, если ваш язык поддерживает даты, которые вы будете иметь в своей базе данных.

Джоэл Браун
источник
1
Если вы используете SQL Server 2008+, DATETIME2 является ответом . Диапазон дат: с 1 января 1 г. по 31 декабря 9999 г. н.э.
Ник Чаммас
1
Хорошее предложение. Для других систем я бы дополнительно порекомендовал CHECKограничение для принудительного применения формата строки даты. Увы, MySQL не применяет CHECK ограничения.
Ник Чаммас
2
@Nick, согласился с DATETIME2 в SQL Server 2008+, (я буду скучать по 1753), но OP начинает с MySQL как его доли в земле. Кроме того, даже DATETIME2 падает, как только вам нужно добавить 31 декабря 1 г. до н.э. в свой календарь :)
Джоэл Браун
1
Вы всегда можете добавить столбец BITили, BOOLEANчтобы указать полярность даты. :) Конечно, если вы сделаете это, вы будете самостоятельно, если будете выполнять расчеты в эти даты "BC". Кто знает, какие настройки календаря, которые обычно выполняются для нас библиотечными функциями, будут пропущены при манипулировании «поддельными» датами до нашей эры ...
Ник Чаммас,
1
Марк, причина, по которой я бы порекомендовал строку, состоит в том, что, пока вы правильно ее сформулируете, она будет удобочитаемой (и даже в некоторой степени редактируемой) без какой-либо обработки, и вы сможете создавать специальные функции манипулирования датами с относительной легкостью. Хранение дат в виде чисел ужасно, ужасно неудобно, если только у вас нет библиотеки функций, которая может интерпретировать этот тип кодирования для простых людей. Конечно, когда такая библиотека существует, кодирование даты в виде числа становится гораздо более разумным.
Джоэл Браун
1

Как насчет наличия одного поля с плавающей точкой в ​​таблице, где мы храним даты в числовом формате, например, 2015-10-12 10:12:05 будут храниться 20151012. 101205. Всегда лучше иметь сортировку по одному полю, а не 3 или более разные поля.

Выше логика не работает для нескольких сценариев. Итак, мы конвертировали дату в секунды, считая 1 день = 86400 секунд. Используется отрицательно для дат BC. Работает как положено.

atpatil11
источник
1
отрицательные числа для BC?
Роб Седжвик
1
151012 и 150819 оба были бы в 15AD, -151109 были бы в 15BC
Роб Седжвик