سلام
طبق جستجویی که کردم با فرمول زیر تاریخ قمری به julian day تبدیل میشه
(11 * $year + 3) / 30 + 354 * $year + 30 * $month - ($month - 1) / 2 + $day + 1948440 - 385
که بعدش میشه julian day رو به تاریخ میلادی تبدیل کرد ولی مشکلی که هست اینه که خروجی فرمول بالا یه عدد اعشاریه که من هنوز متوجه نشدم باید تحت چه شرایطی به بالا یا پایین رند بشه یا کلا اعشارش حذف بشه. با شرایط مختلف مثل تعداد روز ماه قمری (29 یا 30) و سال کبیسه امتحان کردم ولی هنوز به نتیجه نرسیدم.
البته برای کاری که میخام انجام بدم تبدیل قمری به شمسی هم جوابگو هست ولی من براش فرمولی نتونستم پیدا کنم.
کسی تو این زمینه تجربه ای داره؟
سلام
تبدیل تاریخ ها به هم ریزه کاری ها و استثنائات نسبتا زیادی داره که باعث میشه ارزش نداشته باشه خودمون از صفر با محاسبه این کار رو انجام بدیم. پیشنهادم استفاده از پکیج ها و کتابخانه های آماده مختلفی هست که قبلا زحمت این بخش رو کشیدن و چرخ رو دوباره اختراع نکنید. فقط کافیه مقدار ورودی تون رو بدید و خروجی رو تحویل بگیرید.
یکسری به آدرس های زیر بزنید فکر کنم کارتون راه بیفته:
@mhyeganeh اگه سوال رو با دقت بخونین من تبدیل تاریخ قمری رو لازم دارم نه شمسی و برای تبدیل تاریخ قمری لایبرری که به درستی کار کنه پیدا نکردم
حق باشماست. متوجه منظورتون برای تاریخ «قمری» نشدم. پکیج های زیر رو امتحان کردید؟
https://github.com/GeniusTS/hijri-dates
https://github.com/maherelgamil/arabicdatetime
البته دومیش پکیج برای لاراول هست. که فکر میکنم باز هم بتونید ازش به نحوی استفاده کنید اگر php خام می نویسید.
کد زیر رو بررسی کن:
function arabicDate($format,$timestamp)
{
/*
$format: [*]hj|ar|en:[jdl][Fmn][Yy][Aa] (php.date function handles the rest chars)
examples:
echo arabicDate('hj:l d-F-Y هـ', time());
echo arabicDate('ar:l d/F - h:iA', time());
*/
$format=trim($format);
if (substr($format,0,1)=='*') {
$use_span=true;
$format=substr($format,1);
} else $use_span=false;
$type=substr($format,0,3);
$arDay = array("***"=>"السبت", "Sun"=>"الأحد", "Mon"=>"الإثنين", "Tue"=>"الثلاثاء",
"Wed"=>"الأربعاء", "Thu"=>"الخميس", "Fri"=>"الجمعة");
$ampm=array('am'=>'صباحا','pm'=>'مساء');
list($d,$m,$y,$dayname,$monthname,$am)=explode(' ',date('d m Y D M a', $timestamp));
if ($type=='hj:') {
if (($y>1582)||(($y==1582)&&($m>10))||(($y==1582)&&($m==10)&&($d>14))) {
$jd=ard_int((1461*($y+4800+ard_int(($m-14)/12)))/4);
$jd+=ard_int((367*($m-2-12*(ard_int(($m-14)/12))))/12);
$jd-=ard_int((3*(ard_int(($y+4900+ard_int(($m-14)/12))/100)))/4);
$jd+=$d-32076;
} else {
$jd = 367*$y-ard_int((7*($y+5001 + ard_int(($m-9)/7)))/4) + ard_int((275*$m)/9)+$d+1729777;
}
$l=$jd-1948440+10632;
$n=ard_int(($l-1)/10631);
$l=$l-10631*$n+355; // Correction: 355 instead of 354
$j=(ard_int((10985-$l)/5316)) * (ard_int((50*$l)/17719)) + (ard_int($l/5670)) * (ard_int((43*$l)/15238));
$l=$l-(ard_int((30-$j)/15)) * (ard_int((17719*$j)/50)) - (ard_int($j/16)) * (ard_int((15238*$j)/43))+29;
$m=ard_int((24*$l)/709);
$d=$l-ard_int((709*$m)/24);
$y=30*$n+$j-30;
$format=substr($format,3);
$hjMonth = array("محرم", "صفر", "ربيع أول", "ربيع ثاني",
"جماد أول", "جماد ثاني", "رجب", "شعبان", "رمضان", "شوال", "ذو القعدة", "ذو الحجة");
$format=str_replace('j', $d, $format);
$format=str_replace('d', str_pad($d,2,0,STR_PAD_LEFT), $format);
$format=str_replace('l', $arDay[$dayname], $format);
$format=str_replace('F', $hjMonth[$m-1], $format);
$format=str_replace('m', str_pad($m,2,0,STR_PAD_LEFT), $format);
$format=str_replace('n', $m, $format);
$format=str_replace('Y', $y, $format);
$format=str_replace('y', substr($y,2), $format);
$format=str_replace('a', substr($ampm[$am],0,1), $format);
$format=str_replace('A', $ampm[$am], $format);
}
elseif($type=='ar:')
{
$format=substr($format,3);
$arMonth=array("Jan"=>"يناير", "Feb"=>"فبراير","Mar"=>"مارس", "Apr"=>"ابريل", "May"=>"مايو",
"Jun"=>"يونيو", "Jul"=>"يوليو", "Aug"=>"اغسطس", "Sep"=>"سبتمبر", "Oct"=>"اكتوبر",
"Nov"=>"نوفمبر", "Dec"=>"ديسمبر");
$format=str_replace('l', $arDay[$dayname], $format);
$format=str_replace('F', $arMonth[$monthname], $format);
$format=str_replace('a', substr($ampm[$am],0,1), $format);
$format=str_replace('A', $ampm[$am], $format);
}
$date = date($format, $timestamp);
if($use_span) return '<span dir="rtl" lang="ar-sa">'.$date.'</span>';
else return $date;
}
function ard_int($float){return ($float < -0.0000001) ? ceil($float-0.0000001) : floor($float+0.0000001);}
echo arabicDate('hj: l j F Y ',time());
?>
من تست کردم تاریخ میلادی رو به قمری تبدیل میکنه با ۱ روز اختلاف..
کمی قدیمی هست اما احتمالا بتونی فرمول رو از داخلش در بیاری
@mhyeganeh
پکیج اولی رو اگه به issue هاش مراجعه کنید متوجه ایراداتش میشین, البته من قبلا کدش رو بررسی کرده بودم و مناسب نبود.
پکیج دوم هم متاسفانه کاری که من میخام رو انجام نمیده و فرمولی هم که داره استفاده میکنه همونیه که من بالاتر نوشتم و اعشارش رو اصلا در نطر نمیگیره.
@ali.bayat
دقیقا مشکلی که دارم همین یک روز اختلافه 😁 ولی حتما بررسیش میکنم شاید بشه حلش کرد, ممنون.
کلا چرخش ماه به دور زمین، به دقت چرخش زمین به دور خورشید نیست..
برای همینه که میگن تقویم شمسی (خورشیدی) دقت بالایی داره. (سال قمری ۱۱ روز کوتاه تر از سال شمسی هست)
سوای این مطالب یک تاریخ قمری اُمُّالقُری هم داریم:
تقویم رسمی کشور عربستان سعودی است. این تقویم سال ۱۳۴۶ قمری آغاز شد و از سال ۱۴۰۰ قمری زیر نظر گروه نجومی استخراج میشد و از سال ۱۴۲۰ قمری، روز اول هر ماه براساس محاسبه نجومی تولد ماه (مقارنه ماه)، با توجه به غروب خورشید قبل از افول ماه، طبق موقعیت و افق کعبه در شهر مکه تعیین میگردد. این تقویم ممکن است در بعضی ماهها یکروز از تقویم هجری قمری هلالی جلوتر باشد.
که ممکنه الگوریتم بالا بر اساس این نوع تاریخ باشه
به شکل کلی برای تبدیل تاریخ ها یه سری فرمول هست که شاید به دردت بخوره:
پس اگر:
تبدیل هجری قمری به هجری شمسی:
S = [(H × 354) + (H ÷ ۴)] ÷ ۳۶۵
تبدیل هجری شمسی به هجری قمری:
H = [(S × 365) - (S ÷ ۴)] ÷ ۳۵۴
تبدیل هجری قمری به میلادی:
G = H – (H ÷ ۳۳) + ۶۲۲
تبدیل میلادی به هجری قمری:
G = H – (H ÷ ۳۳) + ۶۲۲
@ali.bayat ممنون توضیحاتت خیلی کامل بود.
راستش من دارم سعی میکنم یه لایبرری برای محاسبه تعطیلات رسمی بنویسم, ولی مشکلی که هست اینه که مناسبت های مذهبی براساس تقویم هلالی به دست میان نه تقویم قراردادی.ولی خب الان سایت های تقویم مثل time.ir دارن به درستی تاریخشون رو محاسبه میکنن و منطقی به نظر نمیاد که اطلاعات رو دستی وارد کرده باشن و مطمعنا داره محاسبه میشه.
من خیلی جستجو کردم ولی به جایی نرسیدم برای محاسبه تقویم هلالی.
دقیق ترین سیستم محاسبه ای، سیستم بر پایه ماه هست همانطور که قرآن و احادیث بهش اشاره دارن ولی به غلط میگن خورشید. البته این به معنای غلط بودن خورشید نیست و البته خورشید به معنای تقویم شمسی هم نیست!
بلکه از هر از ماه و هم از درجه ورشید استفاده میشه و تقویم قمری حاصل میشه و به شدت دقیق تر از تقویم شمسی است.
این نکته هم اهمیت داره که کلا تقویمهای فعلی هم اشتباه محاسبه میشن چون بر سر سندیت روایات و فهم قرآن اختلاف هست
خیلی از توسعه دهندهها چون نجوم نمی دانند صرفا دید عددی و کدی دارند که اشتباست و خیال میکنند فرموهای اونها درسته.
مثلا همین فرمول بالا اگر به همین راحتی بود که خوب بود!
سلام خسته نباشید چطوری قمری رو به میلادی تبدیل کنم این کد رو استفاده کردم و مشکلم رو برای میلادی به قمری برطرف کرد.
@ali.bayat
function HijriToJD($m, $d, $y){
return (int)((11 * $y + 3) / 30) + 354 * $y +
30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
}
سلام دوستان .منم میخوام تاریخ های قمری رو به دست بیارم ولی به صور ت قمری قراردادی مثل تاریخ ام القری حساب میشه و توی روزهای برخی از ماه ها یک روزتفاوت داره آیا راه حلی وجود داره مثل سایت time.ir تبدیل تاریخ داشته باشم
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟