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