Skip to content

Commit

Permalink
fix TPublicUtils.IsLeapYear
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamadkh committed Mar 10, 2024
1 parent 584cf31 commit 12f9848
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 46 deletions.
2 changes: 1 addition & 1 deletion SolarCalendarPack.dpk
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ package SolarCalendarPack;
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$DESCRIPTION 'Solar Calendar v3.6.4'}
{$DESCRIPTION 'Solar Calendar v3.6.8'}
{$IMPLICITBUILD OFF}

requires
Expand Down
10 changes: 5 additions & 5 deletions SolarCalendarPack.dproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Package</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<ProjectVersion>19.5</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
</PropertyGroup>
Expand Down Expand Up @@ -93,17 +93,17 @@
<DCCReference Include="dbrtl.dcp"/>
<DCCReference Include="vcldb.dcp"/>
<DCCReference Include="SolarCalendarPackage.pas"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<ProjectExtensions>
Expand Down
128 changes: 88 additions & 40 deletions SolarCalendarPackage.pas
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,12 @@
{* - Bug fix : Fixed ConvertDate method result *}


{* - December 2023 - Azar 1402 *}
{* - version 3.6.6 *}
{* - Bug fix : change Next/Prior buttons functions*}
{* - Bug fix : update datafield when DataField set and after pressing the keys CTRL+D *}
{* - Bug fix : update datafield when DataField set and after entering the information and leaving the editbox *}
{* - March 2024 - Esfand 1402 *}
{* - version 3.6.8 *}
{* - Bug fix : fix TPublicUtils.IsLeapYear *}
{* - Bug fix : change Next/Prior buttons functions *}
{* - Bug fix : update DataField when DataField set and after pressing the keys CTRL+D *}
{* - Bug fix : update DataField when DataField set and after entering the information and leaving the editbox *}



Expand Down Expand Up @@ -379,11 +380,13 @@ TDateFormatInfo = record


LeapMonth: array[TDateKind] of Byte = (12 {Esfand}, 2 {February});

DaysOfMonths: array[TDateKind, 1..12] of Byte = (
( 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 )
( 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 )
{ Far, Ord, Kho, Tir, Mor, Sha, Meh, Aba, Aza, Day, Bah,^Esf },
( 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 )
( 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 )
{ Jan,^Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec });

DaysToMonth: array[TDateKind, 1..13] of Word = (
( 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 365 )
{ Far, Ord, Kho, Tir, Mor, Sha, Meh, Aba, Aza, Day, Bah,^Esf, *** },
Expand Down Expand Up @@ -1855,7 +1858,7 @@ class procedure TPublicUtils.ResetYMD(Date: string; var Year, Month, Day: word;
class function TPublicUtils.IsLeapYear(DateKind: TDateKind; Year: Word): Boolean;
begin
if DateKind = dkSolar then
Result := ((((LongInt(Year) + 38) * 31) mod 128) <= 30)
Result := (Year mod 33) in [1, 5, 9, 13, 17, 22, 26, 30]
else
Result := ((Year mod 4) = 0) and (((Year mod 100) <> 0) or ((Year mod 400) = 0));
end;
Expand Down Expand Up @@ -1929,26 +1932,39 @@ class function TPublicUtils.DateOfDay(DateKind: TDateKind; Days, Year: Word; var

class function TPublicUtils.GregorianToSolar(var Year, Month, Day: Word): Boolean;
var
GregorianYear: integer;
LeapDay, Days: Integer;
PrevGregorianLeap: Boolean;
begin
if IsDateValid(dkGregorian, Year, Month, Day) then
begin
PrevGregorianLeap := IsLeapYear(dkGregorian, Year - 1);
Days := DaysToDate(dkGregorian, Year, Month, Day);
Dec(Year, 622);
if IsLeapYear(dkSolar, Year) then
LeapDay := 1
if Month > 2 Then
GregorianYear := (Year + 1)
else
LeapDay := 0;
if PrevGregorianLeap and (LeapDay = 1) then
Inc(Days, 287)
GregorianYear := Year;

Days := 355666 + (365 * Year) + ((GregorianYear + 3) Div 4) - ((GregorianYear + 99) Div 100);

Days := Days + ((GregorianYear + 399) Div 400) + Day + DaysToMonth[dkGregorian, Month];
Year := -1595 + (33 * (days Div 12053));
Days := Days Mod 12053;
Year := Year + (4 * (Days Div 1461));
Days := Days Mod 1461;

if Days > 365 Then
begin
Year := Year + ((Days - 1) Div 365);
Days := (Days - 1) Mod 365;
end;

if Days < 186 Then
begin
Month := 1 + (Days Div 31);
Day := 1 + (Days Mod 31);
end
else
Inc(Days, 286);
if Days > (365 + LeapDay) then
begin
Inc(Year);
Dec(Days, 365 + LeapDay);
Month := 7 + ((Days - 186) Div 30);
Day := 1 + ((Days - 186) Mod 30);
end;

Result := DateOfDay(dkSolar, Days, Year, Month, Day);
Expand All @@ -1960,38 +1976,70 @@ class function TPublicUtils.GregorianToSolar(var Year, Month, Day: Word): Boolea

class function TPublicUtils.SolarToGregorian(var Year, Month, Day: Word): Boolean;
var
LeapDay, Days: Integer;
PrevSolarLeap: Boolean;
LeapDay, Days: integer;
iCounter: integer;
sal_a: array[0..12] of LongInt;
begin
if IsDateValid(dkSolar, Year, Month, Day) then
begin
PrevSolarLeap := IsLeapYear(dkSolar, Year-1);
Days := DaysToDate(dkSolar, Year, Month, Day);
Inc(Year, 621);
Year := Year + 1595;
Days := -355668 + (365 * Year) + ((Year Div 33) * 8) + (((Year Mod 33) + 3) Div 4) + Day;

if IsLeapYear(dkGregorian, Year) then
LeapDay := 1
if Month < 7 Then
Days := Days + ((Month - 1) * 31)
else
LeapDay := 0;
Days := Days + ((Month - 7) * 30) + 186;

if PrevSolarLeap and (LeapDay = 1) then
Inc(Days, 80)
else
Inc(Days, 79);
Year := 400 * (Days Div 146097);
Days := Days Mod 146097;

if Days > (365 + LeapDay) then
begin
Inc(Year);
Dec(Days, 365 + LeapDay);
end;
if days > 36524 Then
begin
Days := days - 1;
Year := Year + (100 * (Days Div 36524));
Days := Days Mod 36524;

if days >= 365 Then
Days := Days + 1;
end;

Year := Year + (4 * (Days Div 1461));
Days := days Mod 1461;

if Days > 365 Then
begin
Year := Year + ((Days - 1) Div 365);
Days := (days - 1) Mod 365;
end;

Day := days + 1;
Month := 1;

if ((((Year Mod 4) = 0) And ((Year Mod 100) <> 0)) Or ((Year Mod 400) = 0)) Then
LeapDay := 29
else
LeapDay := 28;

for iCounter := 1 to 12 do
begin
if ((iCounter = 2) and (Day <= LeapDay)) or
((iCounter <> 2) and (Day <= DaysOfMonths[dkGregorian, iCounter])) Then
break;

Month := Month + 1;

if iCounter <> 2 then
Day := Day - DaysOfMonths[dkGregorian, iCounter]
else
if iCounter = 2 then
Day := Day - LeapDay;
end;

Result := DateOfDay(dkGregorian, Days, Year, Month, Day);
end
else
Result := False;
end;


class function TPublicUtils.IntGetWeekRemainDays(Date: string; DateKind: TDateKind): integer;
var
Year, Month, Day, TempDay: Word;
Expand Down

0 comments on commit 12f9848

Please sign in to comment.