یک تابع فقط یک مقدار رو میتونه برگردونه پس لازمه که از یک روتین (Procedure) استفاده کنیم نه تابع (Function).
برای سادگی کار تاریخ رو به صورت نوع زیر نگه میداریم:
TDate = record
Year: Integer;
Month: Integer;
Day: Integer;
end;
و تاریخهای حاصل رو در آرایهای به صورت قرار میدیم:
TDateArray = array[1..MaxDateCount] of TDate;
با دید از بالا به پایین (Top-Down) ابتدا الگوریتم به این صورت است که باید دوره زمانی را که بر حسب روز است به تاریخ شروع اضافه کنیم و تا وقتی که تاریخ حاصل کوچکتر یا مساوی تاریخ پایانی است به این عمل ادامه دهیم.
procedure DatePriords(const StartDate, EndDate: TDate; Period: Integer;
out Dates: TDateArray; out DateCount: Integer);
var
ThisDate: TDate;
begin
DateCount := 0;
ThisDate := StartDate;
AdvanceDate(ThisDay, Period);
while CompareDate(ThisDate, EndDate) <= 0 do
begin
DateCount := DateCount + 1;
Dates[DateCount] := ThisDate;
AdvanceDate(ThisDay, Period);
end;
end;
در کد بالا تابع CompareDate دو پارامتر از نوع تاریخ دریافت میکند و نتیجه مقایسه را بصورت زیر برمیگرداند:
- اگر تاریخ اول کوچکتر از تاریخ دوم بود مقداری کوچکتر از صفر برمیگرداند
- اگر دو تاریخ با هم برابر بودند مقدار صفر را برمیگرداند
- اگر تاریخ اول بزرگتر از تاریخ دوم بود مقداری بزرگتر از صفر برمیگرداند
function CompareDate(const Date1, Date2: TDate): Integer;
begin
if Date1.Year = Date2.Year then
if Date1.Month = Date2.Month then
CompareDate := Date1.Day - Date2.Day
else
CompareDate := Date1.Month - Date2.Month
else
CompareDate := Date1.Year - Date2.Year
end;
و همچنین روال AdvanceDate یک تاریخ و تعداد روز رو به صورت آرگومان گرفته و تعداد روز را به تاریخ اضافه میکند (در کد زیر اگر تعداد روز منفی باشد تاریخ حاصل نامعین است). روال کار به اینصورت است که تعداد روز را به روز تاریخ اضافه میکنیم و تا وقتی که روز حاصل از تعداد روزهای ماه بزرگتر بود تعداد روز ماه را از روز تاریخ کم کرده و به یک ماه به جلو میرویم. در این بین اگر ماه از 12 بیشتر شد٬ دوباره از ماه اول شروع کرده و یک سال به جلو میرویم.
procedure AdvanceDate(var Date: TDate; Days: Integer);
begin
Date.Day := Date.Day + Days;
while Date.Day > DaysOfMonth(Year, Month) do
begin
Date.Day := Date.Day - DaysOfMonth(Year, Month);
Date.Month := Date.Month + 1;
if Date.Month > 12 then
begin
Date.Month := 1;
Date.Year := Date.Year + 1;
end;
end;
end;
تابع DaysOfMonth تعداد روزهای یک ماه را برمیگرداند. تعداد روزهای ماه در شش ماهه اول سال 31 و در شش ماهه دوم 30 روز است. البته اگر سال کبیسه نبود اسفندماه 29 روز خواهد داشت.
function DaysOfMonth(Year, Month: Integer): Integer;
begin
if Month <= 6 then
DaysOfMonth := 31
else if (Month < 12) or IsLeapYear(Year) then
DaysOfMonth := 30
else
DaysOfMonth := 29
end;
تابع IsLeapYear تعیین میکند که آیا سال مشخص شده توسط آرگومان تابع یک سال کبیسه است یا نه.
function IsLeapYear(Year: Integer): Boolean;
begin
IsLeapYear := ((((Year + 38) * 31) mod 128) <= 30)
end;
لطفا" برای دفعات بعد عنوان مناسبی برای پستهای خود انتخاب کنید.