Если вы пишете свой собственный, как я предполагаю, вы собираетесь, я бы создал класс, который содержит TDateTime и другие поля, и я бы основывал его на функциональности очень хорошо написанного расширения mxDateTime для Python, котороеявляется очень легко читаемым, открытым кодом, кодом C, который вы можете использовать для извлечения логики григорианского календаря, которая вам понадобится.
В определенных пределах TDateTime всегда прав.Это значение эпохи (0) - 30 декабря 1899 года в полночь.Оттуда вы можете рассчитать другие числа юлианского дня.Он поддерживает отрицательные значения, и, следовательно, он будет поддерживать более 400 лет.Я верю, что вы начнете вносить исправления во время последних реформ григорианского календаря.Если вы уйдете с пятницы, 15 октября 1582 года, и определите номер его юлианского дня, а также проведете реформы до и после этого, вы сможете сделать все, что вам нужно.Имейте в виду, что до 1899 года время «бежит назад», но это просто проблема человеческих голов, компьютер будет точным и вычислит количество минут и секунд, вплоть до предела с плавающей запятой двойной точностиматематика для тебяПридерживайтесь TDateTime в качестве базы.
Я нашел действительно старый код BorlandPascal / TurboPascal, который обрабатывает очень широкий диапазон дат здесь .
Если вам нужно работать с арабскими, еврейскими и другими календарями,Опять же, я отсылаю вас к Python как отличному источнику рабочих примеров.Не только расширение mxdatetime, но и такие вещи, как this .
Для сохранения базы данных вам может потребоваться, чтобы ваше хранилище дат основывалось на числах юлианских дней, а ваше время в секундах, подобных C, с полуночи, если максимальное разрешение, которое вам нужно, составляет 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 Modeling, чем я, так что если вы опубликуете эту диаграмму, я бы проголосовал за нее, и это было бы так.Что касается меня, я буду хранить три поля;Поле Datetime, которое нормализовано к современным календарным стандартам, текстовое поле (произвольная форма), содержащее исходную научную дату в любой форме, и несколько других полей, которые являются внешними ключами таблицы поиска подтипов, чтобы помочь мне упорядочить и искать по датампо дате и подтипу.Это было бы ЭТО для меня.