Функция принимает два параметра: aa (строка, представляющая персидскую дату) и ResultKind (опциональный параметр, определяющий формат возвращаемой даты).
Внутренние функции и переменные
functionTrueTo1(co:Boolean):Integer;constConm_mons:array[0..11]ofByte=...;// длина месяцев в годах без високосных летLeapYearSh:array[0..4]ofInteger=...;// персидские високосные годы (коротко)LeapYearMi:array[0..4]ofInteger=...;// григорианские високосные годы (средне)monthes:array[0..11]ofShortString=...;// имена месяцев на английском языкеtypedate=recordda_day,da_mon,da_year:Integer;end;varm_mons:array[0..11]ofByte;// длина месяцев (инициализировано позднее)LastDayCountSh,LastDayCountMi:integer;// количество дней для персидской и григорианской календарейa,b:date;// записи датыsYY,sMM,sDD:ShortString;// строковые представления года, месяца и дняI:Integer;
Функция определяет несколько внутренних функций и переменных:
TrueTo1: простая функция, конвертирующая булевое значение в целочисленное (0 или 1).
Conm_mons, LeapYearSh и LeapYearMi - массивы байтов и целочисленных значений соответственно, содержащие информацию о длине месяцев и високосных годах в обеих календарях.
monthes - массив строковых значений, содержащий имена месяцев на английском языке.
date - тип записи даты с тремя целочисленными полями: день, месяц и год.
m_mons, LastDayCountSh и LastDayCountMi - переменные, используемые для расчета количества дней в обеих календарях.
a и b - записи даты, используемые для хранения входной и выходной дат соответственно.
sYY, sMM и sDD - строковые переменные, используемые для строительства строки вывода даты.
I - целочисленная переменная, используемая как счетчик цикла.
Логика основной функции
begin// Инициализация массива длины месяцевforI:=Low(Conm_mons)toHigh(Conm_mons)dom_mons[I]:=Conm_mons[I];// Парсинг входной строки даты в записи переменныхa.da_day:=StrToNum(Copy(aa,DayPosInDate,DayLen));a.da_mon:=StrToNum(Copy(aa,MonthPosInDate,MonthLen));a.da_year:=StrToNum(Copy(aa,YearPosInDate,YearLen));// Коррекция года для персидской календариb.da_year:=a.da_year+621;Inc(b.da_year,TrueTo1(((a.da_mon>10)or((a.da_mon=10)and(a.da_day>=12)))or((LeapYearSh[(a.da_year-1374)div4]<>a.da_year)and((a.da_mon=10)and(a.da_day=11))))));// Коррекция месяца для персидской календариInc(m_mons[1],TrueTo1(LeapYearMi[(b.da_year-1996)div4]=b.da_year));// Расчет количества дней для персидской календариif(a.da_mon<=7)thenLastDayCountSh:=((a.da_mon-1)*31+a.da_day)elseLastDayCountSh:=(186+(a.da_mon-7)*30+a.da_day);// Расчет количества дней для григорианской календари (если необходимо)if(b.da_year=(a.da_year+622))thenLastDayCountMi:=LastDayCountSh-286-TrueTo1(LeapYearSh[(a.da_year-1375)div4]=a.da_year)elseLastDayCountMi:=(LastDayCountSh+79);// Коррекция дня для григорианской календариb.da_day:=LastDayCountMi;b.da_mon:=0;while(LastDayCountMi>m_mons[b.da_mon])dobeginDec(LastDayCountMi,m_mons[b.da_mon]);Inc(b.da_mon);b.da_day:=LastDayCountMi;end;Inc(b.da_mon);// Строительство строки вывода датыifb.da_year<1000thensYY:=sYY+'0';ifb.da_year<100thensYY:=sYY+'0';ifb.da_year<10thensYY:=sYY+'0';sYY:=sYY+IntToStr(b.da_year);ifb.da_mon<10thensMM:=sMM+'0';sMM:=sMM+IntToStr(b.da_mon);ifb.da_day<10thensDD:=sDD+'0';sDD:=sDD+IntToStr(b.da_day);caseResultKindof0:Persia_to_Ger_date:=sYY+'/'+sMM+'/'+sDD;1:Persia_to_Ger_date:=sYY+' '+monthes[b.da_mon-1]+' '+sDD;end;end;
Логика основной функции следующая:
Инициализация массива длины месяцев.
Парсинг входной строки даты в записи переменных с помощью StrToNum и Copy.
Коррекция года для персидской календари, добавление 621 и возможное увеличение на основе високосных лет.
Коррекция месяца для персидской календари, учитывая високосные годы.
Расчет количества дней для персидской календари на основе месяца и дня.
Если необходимо, расчет количества дней для григорианской календари и коррекция дня.
Строительство строки вывода даты с использованием корректированных года, месяца и дня.
Функция возвращает строку, представляющую конвертированную дату в одном из двух форматов: YYYY/MM/DD (по умолчанию) или YYYY MMM DD (если ResultKind равен 1).
Преобразует Персидскую дату в дату по Грегорианскому календарю с помощью алгоритма, использующего различные константы и функции для определения високосных лет и дней месяца.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.