Hi everyone,

In addition to the Gregorian calender, there are other calenders such as Hijri calenders (islamic calendar) and Chinese calendar (lunisolar calendar) and may more calenders existed.

I am interested to include the Hijri calender with this module if it is possible.

To convert Gregorian to Hijri, I may use this code:

<?php
// convert christian date to Istamic date
function chrToIsl($cday,$cmonth,$cyear) {
   
$d=$cday;
   
$m=$cmonth;
   
$y=$cyear;
                    if ((
$y>1582)||(($y==1582)&&($m>10))||(($y==1582)&&($m==10)&&($d>14)))
                        {
                       
$jd=(int)((1461*($y+4800+(int)(($m-14)/12)))/4)+(int)((367*($m-2-12*((int)(($m-14)/12))))/12)-
    (int)( (
3* ((int)(  ($y+4900+    (int)( ($m-14)/12)     )/100)    )   ) /4)+$d-32074;
                        }
                        else
                        {
                       
$jd = 367*$y-(int)((7*($y+5001+(int)(($m-9)/7)))/4)+(int)((275*$m)/9)+$d+1729777;
                        }
                   
$l=$jd-1948440+10632;
                   
$n=(int)(($l-1)/10631);
                   
$l=$l-10631*$n+353;
                   
$j=((int)((10985-$l)/5316))*((int)((50*$l)/17719))+((int)($l/5670))*((int)((43*$l)/15238));
                   
$l=$l-((int)((30-$j)/15))*((int)((17719*$j)/50))-((int)($j/16))*((int)((15238*$j)/43))+29 ;
                   
$m=(int)((24*$l)/709);
                   
$d=$l-(int)((709*$m)/24);
                   
$y=30*$n+$j-30;
return array(
$m,$d,$y);
}
//convert islamic to christian
function islToChr($hday,$hmonth,$hyear) {
   
$d=$hday;
   
$m=$hmonth;
   
$y=$hyear;
   
$jd=(int)((11*$y+3)/30)+354*$y+30*$m-(int)(($m-1)/2)+$d+1948440-385;
                    if (
$jd> 2299160 )
                        {
                        
$l=$jd+68569;
                        
$n=(int)((4*$l)/146097);
                       
$l=$l-(int)((146097*$n+3)/4);
                        
$i=(int)((4000*($l+1))/1461001);
                       
$l=$l-(int)((1461*$i)/4)+31;
                        
$j=(int)((80*$l)/2447);
                       
$d=$l-(int)((2447*$j)/80);
                       
$l=(int)($j/11);
                       
$m=$j+2-12*$l;
                       
$y=100*($n-49)+$i+l;
                        }
                    else
                        {
                        
$j=$jd+1402;
                        
$k=(int)(($j-1)/1461);
                        
$l=$j-1461*$k;
                        
$n=(int)(($l-1)/365)-(int)($l/1461);
                        
$i=$l-365*$n+30;
                       
$j=(int)((80*$i)/2447);
                       
$d=$i-(int)((2447*$j)/80);
                       
$i=(int)($j/11);
                       
$m=$j+2-12*$i;
                       
$y=4*$k+$n+$i-4716;
                        }
return array(
$d,$m,$y);
}
?>

Or I may use this code to use Arabic words for days and months:

<?php
 
function arabicDate($format, $timestamp) {
/*
  written by Salah Faya (visualmind@php.net) [url]http://www.php4arab.info/scripts/arabicDate[/url]
$format: [*]hj|ar|en:[jdl][Fmn][Yy][Aa]  (php.date function handles the rest chars)
  * will add <span dir=rtl lang=ar-sa>..</span>
  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("Sat"=>"السبت", "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-32075;
} 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);
}  
?>

Any ideas how and where I should insert any of these code in the date module?

Thank you

Comments

Component:iCal API» Date API

I think a generalized pluggable "use your own calendar" as .inc would be a really good addition. This can be via a function like date_calendar_list() in settings, and checkboxes to enable the various calendars.

In case of Hijri, conversion as per the above code is provided, but it will not be accepted as, because of:
a) code style in not Drupal.
b) It is not pluggable.

Title:Is it possible to add this code to Date module (date converter)?Add support for pluggable calendars in Date API

I am changing the title of this issue to make it more general. The Hijri calendar is just an instance of a calendar.

If we make calendars pluggable, then anyone can write their own.

The easiest instance is how to convert a given date from Gregorian to another calendar, which is what the above code provides.

An example of how to provide an API, is here, where you have a directory and in it, several .inc. An interface to select calendars from, and functions to convert between them.

So, this is more of a call for action for everyone, so we can have multiple calendars.

This is a big project that needs to be thought through. I started a wiki page in g.d.o. at http://groups.drupal.org/node/10607. Please add to that page anything that might be useful.

Marat
In the meantime, I've just used your code on a page to show Islamic date alongside Gregorian and it returned a day early - is that some kind of leap year effect?

Anyway, I thought this might also be useful for anyone wanting to use this with the month name instead of the number:
Just before the end of the chrToIsl function insert the following and change the return line

                    //and get the month names in there
                    $months = array("Muharram", "Safar", "Rabia Awal", "Rabia Thani", "Jumaada Awal", "Jumaada Thani", "Rajab", "Sha'ban", "Ramadan", "Shawwal", "Dhul-Qi'dah", "Dhul-Hijjah");
$M = $months[$m-1];
return array($d,$M,$y);
}

Thanks

Version:5.x-2.x-dev» 6.x-2.x-dev

Moving D5 feature requests that aren't going to get into the initial official 5.2 release to be D6 feature requests that could potentially be backported to D5.2.

Does anyone know of a core issue filed to handle non-Gregorian dates and calendars?

Did you see this module (http://drupal.org/project/calendar_systems)?

I actually did, but I was wondering if this could be handled in core. You see, IMHO it still misses a lot of things in order to be considered feature-complete (only a few calendars supported being its major drawback). Also there's like only ~100 people using it and it's been around roughly for about a year, but it does seem that it is the only decent choice. I'm not saying that it doesn't look promising or anything, but if it was in core I guess it would get more attention and get developed a bit faster.

I guess first things first ...date should get in core first ;)

Hi everyone,

Is there any other ways found since this thread last request?

Till now, The only way to show date is to override Views Field with PHP code or use a client-side Java Script.
Calendar System Module requires core hacking to make a custom function call (calling locale date instead of default date); That is not a professional method.

I think changing this module is not that hard. Therefore, we must change the date_locale to have our formats and the the date_api somehow to have our rule of calendar.

Any comments?