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