Skip to content
 

الگوریتم گاهشماری ایرانی برای نرم‌افزارهای مبدل تقویم‌ها

اکنون نرم‌افزارهای گوناگونی برای تبدیل متقابل تقویم ایرانی (هجری خورشیدی/ هجری شمسی) به دیگر تقویم‌ها وجود دارد که هر یک از آنها محاسن و معایبی در قیاس با یکدیگر دارند. مهم‌ترین کمبود بیشتر نرم‌افزارها، بهره‌گیری از الگوریتم‌هایی با دامنه خطای بالا و کم‌کارآمد، دامنه کوتاه مدت سال‌های تطبیق‌پذیر و بسنده‌کردن به تبدیل تقویم ایرانی با تقویم میلادی گریگوری است.

مناسب‌ترین و کارا‌ترین الگوریتم برای نظام کبیسه‌گیری و نیز تبدیل گاهشماری ایرانی، الگوریتمی است که متکی به 683 روز افزوده برای 683 سال کبیسه با قواعد خاص توزیعی خود در یک دوره بزرگ 2820 ساله باشد. در این صورت، طول متوسط سال تعریف‌شده یا طول سال تقویمی ایرانی برابر است با 242199/365 روز یا 365 روز و 5 ساعت و 48 دقیقه و 46 ثانیه. دامنه خطای عملی در مقایسه با تعریف‌های بنیادین این نظام برابر است با 00000041844/0 روز یا 036/0 ثانیه در سال و یا یک ثانیه در هر 28 سال و 102 ثانیه در هر دوره 2820 ساله. (این دقت در گاهشماری میلادی گریگوری 43/4 ثانیه و در گاهشماری میلادی ژولی 675 ثانیه در سال است.)

بکارگیری قواعد محاسباتی دوره 2820 ساله و دستگاه توزیع روزهای افزوده در 683 سال کبیسه‌ مفروض آن، منجر به ایجاد کارآمدترین نظام ممکن برای تبدیل تقویم‌ها (Calendar converter) و به ویژه در قیاس با تقویم طبیعی خواهد شد.

الگوریتم زیر یکی از بهترین نمونه‌ها بر اساس دوره 2820 ساله است که در بسیاری از برنامه‌های تبدیلی تقویم‌های جهان بکار می‌رود. این الگوریتم را به تازگی آقای مارک جیسون دومینوس (Mark Jason Dominus) به زبان برنامه‌نویسی «پرل» (Perl) نیز نوشته که در پایان همین صفحه آمده است. آقای جان واکر John Walker  نیز در سال 2006 گونه توسعه یافته این الگوریتم را در برنامه قدرتمند Formilab  بکار گرفته و نیز در Calendar Home از آن اقتباس شده است.  برای استفاده عملی از این الگوریتم به نرم‌افزار تبدیل تقویم‌ها مراجعه کنید.

نگارنده این دو برنامه را که از الگوریتم یکسانی بهره گرفته‌اند، برای دویست سال گوناگون در یک دامنه پنج‌هزار ساله که از ترکیب‌های کبیسه‌ متنوعی برخوردار بوده‌اند، آزمایش کرده و به نتیجه نادرستی برخورد نکرده است. این آزمایش برای تبدیل تقویم ایرانی و بالعکس به میلادی ژولی، میلادی گریگوری، هجری قمری، عبرانی و روز ژولی انجام شد.

یادآور می‌شود که برای داده‌های تاریخی که نتیجه تبدیل آنها به تقویم میلادی یا برعکس، سال‌های پیش از 1582 میلادی باشد، می‌باید به دستگاه میلادی ژولی (و نه میلادی گریگوری) رجوع کرد. همچنین برای برخی داده‌های تاریخی پس از سال 1582 نیز می‌باید به تقویم میلادی ژولی مراجعه کرد. چرا که تقویم گریگوری در زمانی یکسان در همه کشورها پذیرفته نشده و رویدادهای تاریخی در آن کشورها گاه تا چند سده بعد همچنان به تقویم میلادی ژولی ثبت شده‌اند. این دو نکته، از خطاهای متداول در تبدیل تقویم‌ها است. خطای متداول دیگر، بی‌توجهی به وجود سال صفر در گاهشماری میلادی گریگوری است. چنانچه کاربر به هر دلیلی قصد داشته باشد رویداد خاصی را با تعمیم تقویم میلادی گریگوری به گذشته به دست آورد، می‌باید این نکته را در نظر داشت که این گاهشماری دارای سال صفر تعریف‌شده (برابر با سال 1- ژولی) است. به عبارت دیگر برای سال‌های پیش از مبدأ میلادی، تفاوتی یک ساله در سالشماری میلادی گریگوری و ژولی وجود دارد.

1. Let a = (y + 2345) % 2820
2. If a is 2819, y is a leap year. Otherwise,
3. Let b = a % 128.
4. If b < 29, let c = b. Otherwise, let c = (b – 29) % 33.
5. If c = 0, y is not a leap year. Otherwise,
6. If c is a multiple of 4, y is a leap year. Otherwise,
7. y is not leap year.
——————————
#!/usr/bin/perl

# is Persian year y a leap year in the Persian calendar?
sub is_leap_year {
my $y = shift;
my $a = ($y + 2345) % 2820;

return 1 if $a == 2819;

my $b = $a % 128;
my $c;
if ($b < 29) { $c = $b }
else { $c = ($b – 29) % 33 }
return 0 if $c == 0;
return 1 if $c %4 == 0;
return 0;
}

# Is Gregorian year g a leap year ** in the Persian calendar **?
sub is_gregorian_leap_year {
my $g = shift;
return is_leap_year($g – 2008 + 1386);
}

my $prev;
for (1979 .. 2028) {
my $is = is_g_leap_year($_);
printf “%4d %s\n”, $_, $is ? “*” : ” “;
die if $is && $prev;
$prev = $is;
#  $ct++ if $is;
}
#print “>> $ct\n”;

همچنین بنگرید به:

نرم‌افزار تبدیل تقویم‌ها به یکدیگر

web analytics