راکت

تبدیل تاریخ قمری به میلادی در php

12 پاسخ

سلام
طبق جستجویی که کردم با فرمول زیر تاریخ قمری به julian day تبدیل میشه

(11 * $year + 3) / 30 + 354 * $year + 30 * $month - ($month - 1) / 2 + $day + 1948440 - 385

که بعدش میشه julian day رو به تاریخ میلادی تبدیل کرد ولی مشکلی که هست اینه که خروجی فرمول بالا یه عدد اعشاریه که من هنوز متوجه نشدم باید تحت چه شرایطی به بالا یا پایین رند بشه یا کلا اعشارش حذف بشه. با شرایط مختلف مثل تعداد روز ماه قمری (29 یا 30) و سال کبیسه امتحان کردم ولی هنوز به نتیجه نرسیدم.
البته برای کاری که میخام انجام بدم تبدیل قمری به شمسی هم جوابگو هست ولی من براش فرمولی نتونستم پیدا کنم.
کسی تو این زمینه تجربه ای داره؟

ثبت پرسش جدید

پاسخ‌ها

12
محمدحسن یگانه
محمدحسن یگانه
@mhyeganeh

تخصص: Full-Stack Web Developer Freelancer

سلام

تبدیل تاریخ ها به هم ریزه کاری ها و استثنائات نسبتا زیادی داره که باعث میشه ارزش نداشته باشه خودمون از صفر با محاسبه این کار رو انجام بدیم. پیشنهادم استفاده از پکیج ها و کتابخانه های آماده مختلفی هست که قبلا زحمت این بخش رو کشیدن و چرخ رو دوباره اختراع نکنید. فقط کافیه مقدار ورودی تون رو بدید و خروجی رو تحویل بگیرید.
یکسری به آدرس های زیر بزنید فکر کنم کارتون راه بیفته:

https://jdf.scr.ir/
https://github.com/morilog/jalali

thrashzone13
thrashzone13
@thrashzone13

تخصص: PHP Laravel Developer

@mhyeganeh اگه سوال رو با دقت بخونین من تبدیل تاریخ قمری رو لازم دارم نه شمسی و برای تبدیل تاریخ قمری لایبرری که به درستی کار کنه پیدا نکردم

شاید پاسخ شما همین‌جا باشد

محمدحسن یگانه
محمدحسن یگانه
@mhyeganeh

تخصص: Full-Stack Web Developer Freelancer

حق باشماست. متوجه منظورتون برای تاریخ «قمری» نشدم. پکیج های زیر رو امتحان کردید؟

https://github.com/GeniusTS/hijri-dates

https://github.com/maherelgamil/arabicdatetime

البته دومیش پکیج برای لاراول هست. که فکر میکنم باز هم بتونید ازش به نحوی استفاده کنید اگر php خام می نویسید.

علی بیات
علی بیات
@ali.bayat

تخصص: توسعه دهنده ارشد وب

کد زیر رو بررسی کن:

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());

?>

من تست کردم تاریخ میلادی رو به قمری تبدیل میکنه با ۱ روز اختلاف..
کمی قدیمی هست اما احتمالا بتونی فرمول رو از داخلش در بیاری

thrashzone13
thrashzone13
@thrashzone13

تخصص: PHP Laravel Developer

@mhyeganeh
پکیج اولی رو اگه به issue هاش مراجعه کنید متوجه ایراداتش میشین, البته من قبلا کدش رو بررسی کرده بودم و مناسب نبود.
پکیج دوم هم متاسفانه کاری که من میخام رو انجام نمیده و فرمولی هم که داره استفاده میکنه همونیه که من بالاتر نوشتم و اعشارش رو اصلا در نطر نمی‌گیره.

thrashzone13
thrashzone13
@thrashzone13

تخصص: PHP Laravel Developer

@ali.bayat
دقیقا مشکلی که دارم همین یک روز اختلافه 😁 ولی حتما بررسیش میکنم شاید بشه حلش کرد, ممنون.

علی بیات
علی بیات
@ali.bayat

تخصص: توسعه دهنده ارشد وب

@thrashzone13

کلا چرخش ماه به دور زمین، به دقت چرخش زمین به دور خورشید نیست..
برای همینه که میگن تقویم شمسی (خورشیدی) دقت بالایی داره. (سال قمری ۱۱ روز کوتاه تر از سال شمسی هست)

سوای این مطالب یک تاریخ قمری اُمُّ‌القُری هم داریم:

تقویم رسمی کشور عربستان سعودی است. این تقویم سال ۱۳۴۶ قمری آغاز شد و از سال ۱۴۰۰ قمری زیر نظر گروه نجومی استخراج می‌شد و از سال ۱۴۲۰ قمری، روز اول هر ماه براساس محاسبه نجومی تولد ماه (مقارنه ماه)، با توجه به غروب خورشید قبل از افول ماه، طبق موقعیت و افق کعبه در شهر مکه تعیین می‌گردد. این تقویم ممکن است در بعضی ماه‌ها یک‌روز از تقویم هجری قمری هلالی جلوتر باشد.

که ممکنه الگوریتم بالا بر اساس این نوع تاریخ باشه


به شکل کلی برای تبدیل تاریخ ها یه سری فرمول هست که شاید به دردت بخوره:

  • برای تبدیل هجری قمری به هجری خورشیدی: سال قمری را در ۱۱ ضرب کرده، حاصل را بر ۳۶۵ تقسیم می‌کنند. سپس نتیجه را از همان سال قمری تفریق می‌کنند.
  • برای تبدیل هجری قمری به میلادی: سال قمری را در ۳۲ ضرب کرده و نتیجه را بر ۳۳ تقسیم می‌کنند. سپس عدد حاصل را با ۶۲۲ جمع می‌کنند.
  • برای تبدیل هجری خورشیدی به هجری قمری: سال خورشیدی را در ۱۱ ضرب کرده بر ۳۵۴ تقسیم می‌کنند و نتیجه را با همان سال خورشیدی جمع می‌کنند.
  • برای تبدیل میلادی به هجری قمری: سال میلادی را از ۶۲۲ کم کرده و نتیجه را در ۳۳ ضرب می‌کنند. سپس حاصل را بر ۳۲ تقسیم می‌کنند.

پس اگر:

  • سال میلادی گرگوری = G
  • سال هجری قمری = H
  • و سال هجری شمسی = S باشد، داریم:

تبدیل هجری قمری به هجری شمسی:

S = [(H × 354) + (H ÷ ۴)] ÷ ۳۶۵

تبدیل هجری شمسی به هجری قمری:

H = [(S × 365) - (S ÷ ۴)] ÷ ۳۵۴ 

تبدیل هجری قمری به میلادی:

G = H – (H ÷ ۳۳) + ۶۲۲

تبدیل میلادی به هجری قمری:

G = H – (H ÷ ۳۳) + ۶۲۲
thrashzone13
thrashzone13
@thrashzone13

تخصص: PHP Laravel Developer

@ali.bayat ممنون توضیحاتت خیلی کامل بود.
راستش من دارم سعی میکنم یه لایبرری برای محاسبه تعطیلات رسمی بنویسم, ولی مشکلی که هست اینه که مناسبت های مذهبی براساس تقویم هلالی به دست میان نه تقویم قراردادی.ولی خب الان سایت های تقویم مثل time.ir دارن به درستی تاریخشون رو محاسبه میکنن و منطقی به نظر نمیاد که اطلاعات رو دستی وارد کرده باشن و مطمعنا داره محاسبه میشه.
من خیلی جستجو کردم ولی به جایی نرسیدم برای محاسبه تقویم هلالی.

seraj8
seraj8
@ali.rezaei.fard5

تخصص: وب دولوپر

دقیق ترین سیستم محاسبه ای، سیستم بر پایه ماه هست همانطور که قرآن و احادیث بهش اشاره دارن ولی به غلط میگن خورشید. البته این به معنای غلط بودن خورشید نیست و البته خورشید به معنای تقویم شمسی هم نیست!
بلکه از هر از ماه و هم از درجه ورشید استفاده میشه و تقویم قمری حاصل میشه و به شدت دقیق تر از تقویم شمسی است.
این نکته هم اهمیت داره که کلا تقویم‌های فعلی هم اشتباه محاسبه میشن چون بر سر سندیت روایات و فهم قرآن اختلاف هست

خیلی از توسعه دهنده‌ها چون نجوم نمی دانند صرفا دید عددی و کدی دارند که اشتباست و خیال میکنند فرموهای اونها درسته.
مثلا همین فرمول بالا اگر به همین راحتی بود که خوب بود!

علی
علی
@DevNull

تخصص: برنامه نویس بک اند,backend developer

سلام خسته نباشید چطوری قمری رو به میلادی تبدیل کنم این کد رو استفاده کردم و مشکلم رو برای میلادی به قمری برطرف کرد.
@ali.bayat

سید میثاق موسویان
سید میثاق موسویان
@misaghmoosavian

تخصص: توسعه دهنده

 function HijriToJD($m, $d, $y){
       return (int)((11 * $y + 3) / 30) + 354 * $y +
         30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
    }
زهره بهرام نژاد
زهره بهرام نژاد
@zohreh

سلام دوستان .منم میخوام تاریخ های قمری رو به دست بیارم ولی به صور ت قمری قراردادی مثل تاریخ ام القری حساب میشه و توی روزهای برخی از ماه ها یک روزتفاوت داره آیا راه حلی وجود داره مثل سایت time.ir تبدیل تاریخ داشته باشم

برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام