Hi

these is my contribution to implement islamic (hijri) calendar.

Waiting for your suggestions.

diff -N -u -r source/php-4.3.8/ext/calendar/calendar.c 
compiled/php-4.3.8/ext/calendar/calendar.c
--- source/php-4.3.8/ext/calendar/calendar.c    2003-08-28 21:01:24.000000000 +0100
+++ compiled/php-4.3.8/ext/calendar/calendar.c  2004-07-20 15:00:00.000000000 +0100
@@ -44,6 +44,8 @@
        PHP_FE(jewishtojd, NULL)
        PHP_FE(jdtofrench, NULL)
        PHP_FE(frenchtojd, NULL)
+       PHP_FE(jdtohijri, NULL)
+       PHP_FE(hijritojd, NULL)
        PHP_FE(jddayofweek, NULL)
        PHP_FE(jdmonthname, NULL)
        PHP_FE(easter_date, NULL)
@@ -81,6 +83,7 @@
        CAL_JULIAN,
        CAL_JEWISH,
        CAL_FRENCH,
+       CAL_HIJRI,
        CAL_NUM_CALS
 };
 typedef long int (*cal_to_jd_func_t)(int month, int day, int year);
@@ -101,7 +104,8 @@
        { "Gregorian", "CAL_GREGORIAN", GregorianToSdn, SdnToGregorian, 12, 31, 
MonthNameShort, MonthNameLong },
        { "Julian", "CAL_JULIAN", JulianToSdn, SdnToJulian, 12, 31, MonthNameShort, 
MonthNameLong },
        { "Jewish", "CAL_JEWISH", JewishToSdn, SdnToJewish, 13, 30, JewishMonthName, 
JewishMonthName },
-       { "French", "CAL_FRENCH", FrenchToSdn, SdnToFrench, 13, 30, FrenchMonthName, 
FrenchMonthName }
+       { "French", "CAL_FRENCH", FrenchToSdn, SdnToFrench, 13, 30, FrenchMonthName, 
FrenchMonthName },
+       { "Hijri",  "CAL_HIJRI", HijriToSdn, SdnToHijri, 13, 30, HijriMonthName, 
HijriMonthName }
 };
 
 /* For jddayofweek */
@@ -109,7 +113,7 @@
 /* For jdmonthname */
 enum   { CAL_MONTH_GREGORIAN_SHORT, CAL_MONTH_GREGORIAN_LONG,
        CAL_MONTH_JULIAN_SHORT, CAL_MONTH_JULIAN_LONG, CAL_MONTH_JEWISH,
-       CAL_MONTH_FRENCH };
+       CAL_MONTH_FRENCH,CAL_MONTH_HIJRI };
 
 /* for heb_number_to_chars */
 static char alef_bet[25] = "0àلâمنهوçèéëىîًٌٍôِ÷ّùْ";
@@ -120,6 +124,7 @@
        REGISTER_LONG_CONSTANT("CAL_JULIAN", CAL_JULIAN, CONST_CS|CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("CAL_JEWISH", CAL_JEWISH, CONST_CS|CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("CAL_FRENCH", CAL_FRENCH, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("CAL_HIJRI",  CAL_HIJRI, CONST_CS|CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("CAL_NUM_CALS", CAL_NUM_CALS, 
CONST_CS|CONST_PERSISTENT);
        /* constants for jddayofweek */
        REGISTER_LONG_CONSTANT("CAL_DOW_DAYNO", CAL_DOW_DAYNO, 
CONST_CS|CONST_PERSISTENT);
@@ -132,6 +137,7 @@
        REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_LONG",         CAL_MONTH_JULIAN_LONG, 
CONST_CS|CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("CAL_MONTH_JEWISH",                      
CAL_MONTH_JEWISH, CONST_CS|CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("CAL_MONTH_FRENCH",                      
CAL_MONTH_FRENCH, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("CAL_MONTH_HIJRI",                       
CAL_MONTH_HIJRI, CONST_CS|CONST_PERSISTENT);
        /* constants for easter calculation */
        REGISTER_LONG_CONSTANT("CAL_EASTER_DEFAULT",                    
CAL_EASTER_DEFAULT, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("CAL_EASTER_ROMAN",                              
CAL_EASTER_ROMAN, CONST_CS | CONST_PERSISTENT);
@@ -557,6 +563,48 @@
 }
 /* }}} */
 
+/* {{{ proto string jdtohijri(int juliandaycount)
+   Converts a julian day count to a islamic(hijri) calendar date */
+PHP_FUNCTION(jdtohijri)
+{
+       pval **julday;
+       int year, month, day;
+       char date[10];
+
+       if (zend_get_parameters_ex(1, &julday) != SUCCESS) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long_ex(julday);
+       
+       SdnToHijri(Z_LVAL_PP(julday), &year, &month, &day);
+       sprintf(date, "%i/%i/%i", month, day, year);
+
+       RETURN_STRING(date, 1);
+}
+/* }}} */
+
+/* {{{ proto int hijritojd(int month, int day, int year)
+   Converts a islamic(hijri) calendar date to julian day count */
+PHP_FUNCTION(hijritojd)
+{
+       pval **year, **month, **day;
+       int jdate;
+
+       if (zend_get_parameters_ex(3, &month, &day, &year) != SUCCESS) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long_ex(month);
+       convert_to_long_ex(day);
+       convert_to_long_ex(year);
+
+       jdate = HijriToSdn(Z_LVAL_PP(year), Z_LVAL_PP(month), Z_LVAL_PP(day));
+
+       RETURN_LONG(jdate);
+}
+/* }}} */
+
 /* {{{ proto mixed jddayofweek(int juliandaycount [, int mode])
    Returns name or number of day of week from julian day count */
 PHP_FUNCTION(jddayofweek)
@@ -631,6 +679,10 @@
                        SdnToFrench(Z_LVAL_PP(julday), &year, &month, &day);
                        monthname = FrenchMonthName[month];
                        break;
+               case CAL_MONTH_HIJRI:                   /* hijri month */
+                       SdnToHijri(Z_LVAL_PP(julday), &year, &month, &day);
+                       monthname = HijriMonthName[month];
+                       break;
                default:                        /* default gregorian */
                case CAL_MONTH_GREGORIAN_SHORT:                 /* gregorian or julian 
month */
                        SdnToGregorian(Z_LVAL_PP(julday), &year, &month, &day);
diff -N -u -r source/php-4.3.8/ext/calendar/config.m4 
compiled/php-4.3.8/ext/calendar/config.m4
--- source/php-4.3.8/ext/calendar/config.m4     2002-03-12 17:10:56.000000000 +0100
+++ compiled/php-4.3.8/ext/calendar/config.m4   2004-07-20 15:18:09.000000000 +0100
@@ -7,5 +7,5 @@
 
 if test "$PHP_CALENDAR" = "yes"; then
   AC_DEFINE(HAVE_CALENDAR,1,[ ])
-  PHP_NEW_EXTENSION(calendar, calendar.c dow.c french.c gregor.c jewish.c julian.c 
easter.c cal_unix.c, $ext_shared)
+  PHP_NEW_EXTENSION(calendar, calendar.c dow.c french.c gregor.c jewish.c hijri.c 
julian.c easter.c cal_unix.c, $ext_shared)
 fi
diff -N -u -r source/php-4.3.8/ext/calendar/hijri.c 
compiled/php-4.3.8/ext/calendar/hijri.c
--- source/php-4.3.8/ext/calendar/hijri.c       1970-01-01 00:00:00.000000000 +0000
+++ compiled/php-4.3.8/ext/calendar/hijri.c     2004-07-20 14:52:07.000000000 +0100
@@ -0,0 +1,198 @@
+/* $selId: hijri.c,v 1.0 2004/07/20 14:50:00 lees Exp $
+ * Copyright 2004-2004, Mostapha ([EMAIL PROTECTED]), all rights reserved.
+ * Permission granted to use, copy, modify, distribute and sell so long as
+ * the above copyright and this permission statement are retained in all
+ * copies.  THERE IS NO WARRANTY - USE AT YOUR OWN RISK.
+ *
+ * Based on :
+ * hconv.c
+ *
+ * Copyright (c) 1992 by Waleed A. Muhanna
+ *
+ * Send any comments/suggestions/fixes/additions to:
+ *             [EMAIL PROTECTED]
+ *
+ */
+
+#include <math.h>
+#include "sdncal.h"
+
+#define RPD     (0.01745329251994329577) /* radians per degree (pi/180) */
+
+
+char   *dow[7]= {
+       "Ahad", "Ithnain", "Zulatha", "Arbi'a",
+       "Khamees", "Jumma", "Sabt"
+};
+
+char  *HijriMonthName[13] = {"",
+       "Muharram", "Safar", "Rabi` al-Awal", "Rabi` al-Thaani",
+       "Jumaada al-Awal", "Jumaada al-Thaani", "Rajab", "Sha`ban",
+       "Ramadan", "Shawwal", "Zul al-Qi`dah", "Zul al-Hijjah"
+};
+
+char  *HijriMonthAraName[13] = {"",
+       "محرم", 
+       "صفر",
+       "ربيع الأول", 
+       "ربيع الثاني",
+       "جمادى الأول", 
+       "جمادى الثاني", 
+       "رجب",
+       "شعبان",
+       "رمضان",
+       "شوال",
+       "ذو القعدة",
+       "ذو الحجة"
+};
+
+
+/*
+ * Given an integer _n_ and a phase selector (nph=0,1,2,3 for
+ * new,first,full,last quarters respectively, function returns the
+ * Julian date/time of the Nth such phase since January 1900.
+ * Adapted from "Astronomical  Formulae for Calculators" by
+ * Jean Meeus, Third Edition, Willmann-Bell, 1985.
+ */
+double
+tmoonphase( long n, int nph)
+{
+       double jd, t, t2, t3, k, ma, sa, tf, xtra;
+       k = n + nph/4.0;  t = k/1236.85;  t2 = t*t; t3 = t2*t;
+       jd =  2415020.75933 + 29.53058868*k - 1.178e-4 * t2
+           - 1.55e-7 * t3
+           + 3.3e-4 * sin (RPD * (166.56 +132.87*t -0.009173*t2));
+
+       /* Sun's mean anomaly */
+       sa =  RPD * (359.2242 + 29.10535608*k - 3.33e-5 * t2 - 3.47e-6 * t3);
+
+       /* Moon's mean anomaly */
+       ma =  RPD * (306.0253 + 385.81691806*k + 0.0107306*t2 +1.236e-5 *t3);
+
+       /* Moon's argument of latitude */
+       tf = RPD * 2.0 * (21.2964 + 390.67050646*k -0.0016528*t2
+                     -2.39e-6 * t3);
+
+       /* should reduce to interval 0-1.0 before calculating further */
+       if (nph==0 || nph==2)
+               /* Corrections for New and Full Moon */
+               xtra = (0.1734 - 0.000393*t) * sin(sa)
+                     +0.0021*sin(sa*2)
+                     -0.4068*sin(ma) +0.0161*sin(2*ma) -0.0004*sin(3*ma)
+                     +0.0104*sin(tf)
+                     -0.0051*sin(sa+ma) -0.0074*sin(sa-ma)
+                     +0.0004*sin(tf+sa) -0.0004*sin(tf-sa)
+                     -0.0006*sin(tf+ma) +0.0010*sin(tf-ma)
+                     +0.0005*sin(sa+ 2*ma);
+       else if (nph==1 || nph==3) {
+               xtra = (0.1721 - 0.0004*t) * sin(sa)
+                     +0.0021*sin(sa*2)
+                     -0.6280*sin(ma) +0.0089*sin(2*ma) -0.0004*sin(3*ma)
+                     +0.0079*sin(tf)
+                     -0.0119*sin(sa+ma) -0.0047*sin(sa-ma)
+                     +0.0003*sin(tf+sa) -0.0004*sin(tf-sa)
+                     -0.0006*sin(tf+ma) +0.0021*sin(tf-ma)
+                     +0.0003*sin(sa+ 2*ma) +0.0004*sin(sa-2*ma)
+                     -0.0003*sin(2*sa+ma);
+               if (nph==1)
+                       xtra = xtra +0.0028 -0.0004*cos(sa) +0.0003*cos(ma);
+               else
+                       xtra = xtra -0.0028 +0.0004*cos(sa) -0.0003*cos(ma);
+       } else {
+               printf("tmoonphase: illegal phase number\n");
+               exit(1);
+       }
+       /* convert from Ephemeris Time (ET) to (approximate)
+          Universal Time (UT) */
+       jd += xtra - (0.41 +1.2053*t +0.4992*t2)/1440;
+       return (jd);
+}
+
+
+/* parameters for Makkah: for a new moon to be visible after sunset on
+   a the same day in which it started, it has to have started before
+   (SUNSET-MINAGE)-TIMZ=3 A.M. local time. */
+
+#define TIMZ 3.0
+#define MINAGE 13.5
+#define SUNSET 19.5 /*approximate */
+#define TIMDIF (SUNSET-MINAGE)
+
+double
+visible(long n, double *rjd)
+{
+       double jd;
+       float tf;
+       long d;
+
+       jd = tmoonphase(n,0);  *rjd = jd;
+       d = jd;
+       tf = (jd - d);
+       if (tf<=0.5)  /*new moon starts in the afternoon */
+               return(jd+1.0); 
+       /* new moon starts before noon */
+       tf = (tf-0.5)*24 +TIMZ;  /* local time */ 
+       if (tf>TIMDIF) return(jd+1.0);  /*age at sunset < min for visiblity*/
+       return(jd);
+}
+
+
+/*
+ * Given a gregorian/julian date, compute corresponding Hijri date structure
+ * As a reference point, the routine uses the fact that the year
+ * 1405 A.H. started immediatly after lunar conjunction number 1048
+ * which occured on September 1984 25d 3h 10m UT.
+ */
+
+void SdnToHijri (
+                 long int sdn,
+                 int *pYear,
+                 int *pMonth,
+                 int *pDay)
+{
+       int hday,hmon,hyear,y,m,d;
+       double jd, mjd, rjd;
+       long k, hm;
+
+       jd = (double) sdn;
+       SdnToGregorian(sdn,&y,&m,&d);
+       /* obtain first approx. of how many new moons since the beginning
+          of the year 1900 */
+       k = 0.6 + (y + ((int) (m-0.5)) /12.0 + d/365.0 - 1900) *12.3685;
+       do  {mjd = visible(k--, &rjd);} while (mjd>jd);  k++;
+       /*first of the month is the following day*/
+       hm = k -1048;
+       hyear = 1405 + (hm / 12);
+
+       hmon =  (hm % 12) +1;
+       if (hm !=0 && hmon<=0) {hmon +=12; hyear--; }
+       if (hyear<=0) hyear--;
+       *pDay = jd -mjd +1.0;
+       *pMonth = hmon;
+       *pYear =hyear;
+
+       return;
+}
+
+#define NMONTHS  (1405*12+1)
+
+/*
+ * Given a Hijri date, compute corresponding C.E. date structure
+ */
+
+long int HijriToSdn(
+                   int y,
+                   int m,
+                   int d)
+{
+       double jd, rjd;
+       long k;
+
+
+       if (y<0) y++;
+       k = m+ y*12 - NMONTHS;   /* # of months since 1/1/1405 */
+       jd = visible(k+1048L, &rjd) +d;
+
+       return ((long int)jd);
+}
+
diff -N -u -r source/php-4.3.8/ext/calendar/php_calendar.h 
compiled/php-4.3.8/ext/calendar/php_calendar.h
--- source/php-4.3.8/ext/calendar/php_calendar.h        2002-05-12 16:06:04.000000000 
+0100
+++ compiled/php-4.3.8/ext/calendar/php_calendar.h      2004-07-20 14:27:35.000000000 
+0100
@@ -19,6 +19,8 @@
 PHP_FUNCTION(jewishtojd);
 PHP_FUNCTION(jdtofrench);
 PHP_FUNCTION(frenchtojd);
+PHP_FUNCTION(jdtohijri);
+PHP_FUNCTION(hijritojd);
 PHP_FUNCTION(jddayofweek);
 PHP_FUNCTION(jdmonthname);
 PHP_FUNCTION(easter_days);
diff -N -u -r source/php-4.3.8/ext/calendar/sdncal.h 
compiled/php-4.3.8/ext/calendar/sdncal.h
--- source/php-4.3.8/ext/calendar/sdncal.h      2002-10-31 10:16:23.000000000 +0100
+++ compiled/php-4.3.8/ext/calendar/sdncal.h    2004-07-20 14:56:55.000000000 +0100
@@ -86,8 +86,10 @@
 long int FrenchToSdn(int inputYear, int inputMonth, int inputDay);
 extern char *FrenchMonthName[14];
 
-/* Islamic calendar conversions. */
-/* Not implemented yet. */
+/* Islamic (Hijri) calendar conversions. */
+void SdnToHijri(long int sdn, int *pYear, int *pMonth, int *pDay);
+long int HijriToSdn(int inputYear, int inputMonth, int inputDay);
+extern char *HijriMonthName[13];
 
 /* Day of week conversion.  0=Sunday, 6=Saturday */
 int DayOfWeek(long int sdn);

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to