# Native Code > برنامه نویسی در Delphi > کامپوننت های سایر شرکت ها، و توسعه کامپوننت >  تشخیص سال کبیسه شمسی

## SamadYousefi

function IsLeapYear(Year: Word): Boolean;
begin
  Result:= SysUtils.IsLeapYear(Year +1);
end;

----------


## Mohammad_Mnt

اشتباه محض :)
سیستم کبیسه میلادی : هر چهار سال یک بار، به جز سال هایی که به 100 بخش پذیر باشند ولی به 400 بخش پذیر نباشند ( 2000 کبیسه است )
سیستم کبیسه خورشیدی : باقیمانده تقسیم سال به 33 یکی از این عدد ها باشد : 1 و 5 و 9 و 13 و 17 و 22 و 26 و 30

----------


## morteza_1234m

میشه بیشتر توضیح بدید یا یک مثال بزنید

----------


## Mohammad_Mnt

میلادی :
سال 2000 : به 4 بخش پذیره ، به 100 بخش پذیره و به 400 هم بخش پذیره پس کبیسه است
سال 2100 : به 4 بخش پذیره ، به 100 بخش پذیره ولی به 400 بخش پذیر *نیست* پس کبیسه *نیست*

هجری خورشیدی :
سال 1383 : باقیمانده تقسیم 1383 بر 33 می شود 30 ، پس کبیسه است
سال 1385 : باقیمانده تقسیم 1383 بر 33 می شود* 32* ، پس کبیسه *نیست*

----------


## ghabil

[qoute=Mohammad_Mnt]
سیستم کبیسه میلادی : هر چهار سال یک بار، به جز سال هایی که به 100 بخش پذیر باشند ولی به 400 بخش پذیر نباشند ( 2000 کبیسه است )
[/qoute]

برای میلادی که تابع IsLeapYear هست که خودش محاسبه میکنه ،دقیقا به همین روشی که دوستمون گفتن (قسمت دوم رو بولینی ریورس کنید میشه چیزی که گفت) (توی یونیت SysUtils)


function IsLeapYear(Year: Word): Boolean;
begin
  Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
end;


نکته مهم اینه که خیلی دیگه از توابع Date از این تابع استفاده میکنند و اگر براتون مهمه که تفاوتهای شمسی با میلادی در سالهای کبیسه رو داشته باشید باید او هارو هم دوباره بنویسید : مثلا تابع WeeksInYear که البته بنظر م که اصولا اینا قابل چشم پوشی هستند...

----------


## Mohammad_Mnt

این هم که من نوشتم کاملا" دقیق نیست. فکر کنم اطراف سال 1600 هجری خورشیدی اشتباه جواب میده

----------


## SamadYousefi

با تشکر از همه دوستان ،
آنچه که در مورد سال کبیسه میلادی مطرح کردید کاملا صحیح است ولی اگر به تقویم نگاه کنیم می بینیم که سال بعد از سال کبیسه میلادی ، سال کبیسه شمسی است و سه سال بعد از سال کبیسه شمسی سال کبیسه میلادی است .
مثال
میلادی( عادی)     شمسی ( کبیسه)
----------------------------------------
2005                                1383 
توضیح  1- سال 2004 کبیسه بوده است
           2- سال 1384 میلادی سال کبیسه است
           3- اگر سال 1383 سال میلادی فرض شود پس داریم 1384 = 1 + 1383

----------


## Mohammad_Mnt

با یک مثال نقض این فرمول رو می شه رد کرد :
می خواهیم بدانیم سال 1370 کبیسه است یا نه :
طبق فرمول شما: 1371 = 1 + 1370 و سال 1371 میلادی کبیسه نیست پس نتیجه می گیریم که سال 1370 هجری خورشیدی کبیسه نیست !
ولی در واقع سال 1370 کبیسه است !

----------


## محمد دادودنیا

با سلام 
چرا دعوا دارید با اینم تابع کاملش

Function  MiladyToShamsi(var d,m,y:integer;Const DelChar:char='/'):String;
var
ny,nd,nm,dd:integer;
begin
  ny:=0;
  nd:=0;
  nm:=0;
  dd:=0;
  ny:=y-621;
  if m<3 then ny:=ny-1;
  if (m=3) and (d<=20) then ny:=ny-1;
  dd:=0;
  if m=1  then dd:=d;
  if m=2  then dd:=31+d;
  if m=3  then dd:=31+28+d;
  if m=4  then dd:=31+28+31+d;
  if m=5  then dd:=31+28+31+30+d;
  if m=6  then dd:=31+28+31+30+31+d;
  if m=7  then dd:=31+28+31+30+31+30+d;
  if m=8  then dd:=31+28+31+30+31+30+31+d;
  if m=9  then dd:=31+28+31+30+31+30+31+31+d;
  if m=10 then dd:=31+28+31+30+31+30+31+31+30+d;
  if m=11 then dd:=31+28+31+30+31+30+31+31+30+31+d;
  if m=12 then dd:=31+28+31+30+31+30+31+31+30+31+30+d;
  if m<3  then dd:=dd+(366-80);
  if m>3  then dd:=dd-79;
  if (m=3)   and (d<=20)      then dd:=dd+(366-80);
  if (m=3)   and (d>20)       then dd:=dd-79;
  if (dd>=1) and (dd<=(6*31)) then
    begin
      nm:=(dd div 31);
      nd:=(dd-(nm*31));
      IF nd=0 Then nd:=31;
      IF (nm<6) And (nd<>31) Then nm:=nm+1;
    end
  Else
  if dd>186 then
  begin
   dd:=dd-186;
   nm:=7+dd div 30;
   nd:=dd mod 30;
   if nd=0 then
   begin
    nd:=30;
    nm:=nm-1;
   end;
  end;
  d:=nd;
  y:=ny;
  m:=nm;
Result:=inttostr(y)+DelChar+AddZeroToFirst(inttost  r(m),2)+DelChar+AddZeroToFirst(inttostr(d),2);
End;

----------


## Mohammad_Mnt

برای دریافت کد به زبان هایCPHPJavaScript#CTexبه این سایت بروید

----------


## hmahdavi921

در تقویم هجری خورشیدی علاوه بر کبیسه چهارساله، طبق محاسبات نجومی، برای تعدیل دقیقتر (کاستن کبیسه‌ها)، فاصله بعضی کبیسه‌ها یک‌روز بیشتر می‌شود و در هر دورهٔ ۲۹ یا ۳۳ یا ۳۷ ساله، یک کبیسه پنج‌ساله (بجای چهارساله) در آغاز محقق می‌شود.
برای تشخیص کبیسه بودن سال‌های هجری خورشیدی حسابی شیوه یکنواخت وجود دارد اما در گاهشماری رسمی ایران شیوه کاملاً یکنواختی وجود ندارد. چنانچه باقی‌ماندهٔ حاصل تقسیم سال مورد نظر بر عدد ۳۳، یکی از اعداد (۱، ۵، ۹، ۱۳، ۱۷، ۲۲، ۲۶ و ۳۰) باشد،[۱] برای سال‌های بین ۱۲۴۴ تا ۱۳۴۲، آن سال کبیسه است و برای سال‌های ۱۳۴۳ تا ۱۴۷۲ به‌جای ۱۷، باقی‌ماندهٔ ۱۸ ملاک خواهد بود و برای دیگر سال‌ها نیز به مراتب تفاوت‌هایی در اعداد هشتگانه فوق وجود دارد. به عنوان مثال سال ۱۳۹۱ سالی کبیسه است چراکه باقی‌ماندهٔ تقسیم آن بر عدد ۳۳ برابر عدد ۵ است.

----------


## یوسف زالی

از توابع موجود در لینک امضای بنده هم میتونید استفاده کنید.

----------


## gerailly

کبیسه ی شمسی از قائده ی خاصی پیروی نمیکند و دوره ها توسط منجمین تا ۱۵۰۰ مشخص شده که جدول آن در گاه شمار رسمی ایران وجود داره با mod 33 تمام کبیسه ها از اول سال یک تا کنون را نمی شود بدست آورد .. این تابع برای دوره های ۳۳ ساله درست است فرضا طبق جدول از سال ۱۳۷۰ یک دوره ی ۳۳ اتفاق می افتد که ۵ واحد بعد از آن کبیسه ی ۵ ساله ( ۱۳۷۵ ) و بعداز ان ۴ واحد ۴ واحد کبیسه ی چهار ساله اتفاق می افتد . ( ۱۳۷۹ ، ۱۳۸۳ ، ۱۳۸۷ ، ۱۳۹۱ ، ۱۳۹۵ ، ۱۳۹۹ ، ۱۴۰۳ )

----------

