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

Какая структура данных рекомендуется для нескольких календарей, дат и продолжительности?

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

  • Разделите изменения на григорианские календари в разных странах в разное время.
  • Накрыть исторический период не менее 500 лет.
  • Работайте с несколькими типами календарей - лунными, солнечными, китайскими, финансовыми, христианскими, UTC, мусульманами.
  • Сменим изменения в Великобритании на конец года с 31 марта по 31 декабря и сопоставимые изменения в других странах.

Мне также нужно сохранить длительности, которые я определил как разницу между двумя временными метками (дата и время). Это подразумевает необходимость сохранения "нулевой" даты - поэтому я могу хранить длительности, скажем, три с половиной часа; или 10 минут.

У меня детали необходимых вычислений. Временная метка Firebird основана на функции даты, которая начинается с 1 января 100 года н.э., поэтому не может использоваться для продолжительности в том, как мне нужно записывать их. Кроме того, этот тип данных настроен (как и большинство функций timestamp) для записи количества дней с базовой даты; он не предназначен для записи календарных дат.

Может ли кто-нибудь предложить:

  • Структура данных для хранения дат и продолжительности, соответствующих вышеуказанным требованиям ИЛИ
  • Ссылка на такую ​​структуру данных OR
  • Предлагайте рекомендации для подхода к структурированию такого хранилища ИЛИ
  • Любые пункты, которые могут помочь мне в решении.

EDIT:

@Warren P предоставил отличную работу в своих ответах. Я, очевидно, не объяснил, что я ищу достаточно ясно, поскольку его работа концентрируется на вычислениях и способах их вычисления. Все ценные и полезные вещи, но не то, что я хотел рассказать.

У меня есть детали всех вычислений, необходимых для преобразования между различными представлениями дат, и у меня есть довольно хорошее представление о том, как их реализовать (используя такие элементы, как предлагает Уоррен). Тем не менее, мое требование заключается в датах STORE, которые отвечают различным критериям, перечисленным выше. Пример: дата, которую нужно сохранить - "Третий 13 июня Карл II". Я пытаюсь определить подходящую структуру, в которой можно хранить такие даты.

EDIT:

Я внесла поправки в предложенную мной схему. Я перечислил атрибуты в каждой таблице и определил таблицы и атрибуты примерами, указанными в третьем разделе окна сущности. Я использовал пример, приведенный в этом question и ответе в моем определении на примере, и внеся поправки пример в моем вопросе, чтобы соответствовать. Хотя я доказал свою схему, описав какой-то другой пример, эта схема все еще может быть сложной; над анализом; пропустите некоторое очевидное упрощение и может оказаться очень трудным для реализации (действительно, это может быть неправильно). Любые комментарии или предложения были бы наиболее желанными.

enter image description here

4b9b3361

Ответ 1

Если вы пишете свои собственные, как я предполагаю, вы намереваетесь, я бы сделал класс, содержащий TDateTime, и другие поля, и я бы основал его на функциональности в очень красиво написанном расширении mxDateTime для Python, который очень легко читаемый, с открытым исходным кодом, C-код, который вы можете использовать для извлечения gregorian логики календаря, который вам понадобится.

В определенных пределах TDateTime всегда прав. Это значение эпохи (0) - 30 декабря 1899 года в полночь. Оттуда вы можете рассчитать другие числа юлианских дней. Он поддерживает отрицательные значения, и, следовательно, он будет поддерживать более 400 лет. Я считаю, что вы начнете делать исправления во время последних реформ в григорианском календаре. Если вы отправитесь с пятницы, 15 октября 1582 года, и выясните его число юлианских дней, а также реформы до и после этого, вы сможете сделать все, что вам нужно. Имейте в виду, что время дня работает "назад" до 1899 года, но это чисто проблема в головах человека, компьютер будет точным и рассчитает количество минут и секунд до предела с плавающей запятой двойной точности математика для вас. Придерживайтесь TDateTime в качестве базы.

Я нашел действительно старый код BorlandPascal/TurboPascal, который обрабатывает действительно широкий диапазон дат здесь.

Если вам нужно обрабатывать арабские, еврейские и другие календари, я снова отсылаю вас к Python как к большому источнику рабочих примеров. Не только расширение mxdatetime, но и прочее, например .

Для сохранения базы данных вы можете захотеть основать хранилище данных по дням в julian day numbers и ваше время как C-like секунд с полуночи, если максимальное разрешение вам нужно 1 секунду.

Вот фрагмент, с которого я начну, и завершение кода:

TCalendarDisplaySubtype = ( cdsGregorian,cdsHebrew,cdsArabic,cdsAztec,
   cdsValveSoftwareCompany, cdsWhoTheHeckKnows );
TDateInformation = class
      private
         FBaseDateTime:TDateTime;
         FYear,FMonth,FDay:Integer; // if -1 then not calculated yet.
         FCalendarDisplaySubtype:TCalendarDisplaySubtype;
      public 

        function SetByDateInCE(Y,M,D,h,m,s:Integer):Boolean;
        function GetAsDateInCE(var Y,M,D,h,m,s:Integer):Boolean;
        function DisplayStr:String;
        function SetByDateInJewishCalendar( ... );
        property BaseDateTime:TDateTime read FDateTime write FDateTime;
        property JulianDayNumber:Integer read GetJulianDayNumber write SetJulianDayNumber;
        property CalendarDisplaySubType:TCalendarDisplaySubtype;



   end;

Я не вижу причин для того, чтобы хранить как день юлианского дня, так и TDateTime, просто используйте константу, вычитайте/добавьте из значения Trunc (FBaseDateTime) и верните это в функции GetJulianDayNumber, SetJulianDayNumber. Возможно, стоит иметь поля, где вы вычисляете год, месяц, день, для данного календаря, один раз и сохраняете их, делая дисплей как функцию строки намного проще и быстрее.

Обновление: похоже, что вы лучше в моделировании ER, чем я, поэтому, если вы разместите эту диаграмму, я бы ее повысил, и это было бы так. Что касается меня, я бы сохранил три поля; Поле Datetime, нормализованное к современным стандартам календаря, текстовое поле (свободная форма), содержащее исходную научную дату в любой форме и несколько других полей, которые представляют собой таблицу подтипов внешних ключей, чтобы помочь мне организовать и выполнить поиск по датам по дате и подтипу. Это было бы для меня.

Ответ 2

Только частичный ответ, но важная часть.

Поскольку вы собираетесь хранить даты в очень широком диапазоне, где многое происходило с календарями, вам необходимо учитывать эти изменения.

База данных часовых поясов TZ-база данных и Delphi TZDB-обертка вокруг базы данных TZ окажет большую помощь.
У этого есть база данных с правилами, как исторически ведут себя хронометры.

Я знаю, что они основаны на текущих схемах календаря, и вам нужно сначала конвертировать в UTC.

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

Edit:

Схема, которую я использовал бы, будет такой:

  • найти способы конвертации всех ваших календарей в/из UTC
  • сохранить тип календаря
  • сохраните даты в их исходном формате и источник даты (на случай, если ваш источник испорчен, и вам нужно пересчитать).
  • используйте конверты UTC, чтобы перейти от вашего оригинала через UTC к типам календаря в пользовательском интерфейсе.

- Йерун