summaryrefslogtreecommitdiff
path: root/ext/calendar
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2001-07-04 10:12:45 +0000
committerWez Furlong <wez@php.net>2001-07-04 10:12:45 +0000
commita07a26888e1db18be729f10bafe6cf4bbb65ce5f (patch)
treea5f5e8e1e2c3ef383b0a04693ea8919087b2eebe /ext/calendar
parentf1364ebf3ead89f145af573e3b90f3503898b0ad (diff)
downloadphp-git-a07a26888e1db18be729f10bafe6cf4bbb65ce5f.tar.gz
Added a couple of new functions to "modularize" working with calendars.
Added a few constants for the existing functions, and tidied them up a bit.
Diffstat (limited to 'ext/calendar')
-rw-r--r--ext/calendar/CREDITS2
-rw-r--r--ext/calendar/calendar.c284
-rw-r--r--ext/calendar/php_calendar.h5
3 files changed, 244 insertions, 47 deletions
diff --git a/ext/calendar/CREDITS b/ext/calendar/CREDITS
index e69de29bb2..a2904bd8b2 100644
--- a/ext/calendar/CREDITS
+++ b/ext/calendar/CREDITS
@@ -0,0 +1,2 @@
+Calendar
+Shane Caraveo, Colin Viebrock, Hartmut Holzgraefe, Wez Furlong
diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c
index 12ae1aae67..7c06d393fb 100644
--- a/ext/calendar/calendar.c
+++ b/ext/calendar/calendar.c
@@ -15,9 +15,10 @@
| Authors: Shane Caraveo <shane@caraveo.com> |
| Colin Viebrock <cmv@easydns.com> |
| Hartmut Holzgraefe <hartmut@six.de> |
+ | Wez Furlong <wez@thebrainroom.com> |
+----------------------------------------------------------------------+
*/
-/* $Id: */
+/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -43,6 +44,10 @@ function_entry calendar_functions[] = {
PHP_FE(easter_days, NULL)
PHP_FE(unixtojd, NULL)
PHP_FE(jdtounix, NULL)
+ PHP_FE(cal_to_jd, NULL)
+ PHP_FE(cal_from_jd, NULL)
+ PHP_FE(cal_days_in_month, NULL)
+ PHP_FE(cal_info, NULL)
{NULL, NULL, NULL}
};
@@ -50,7 +55,7 @@ function_entry calendar_functions[] = {
zend_module_entry calendar_module_entry = {
"calendar",
calendar_functions,
- NULL, /*PHP_MINIT(calendar),*/
+ PHP_MINIT(calendar),
NULL,
NULL,
NULL,
@@ -62,12 +67,62 @@ zend_module_entry calendar_module_entry = {
ZEND_GET_MODULE(calendar)
#endif
+/* this order must match the conversion table below */
+enum {
+ CAL_GREGORIAN = 0,
+ CAL_JULIAN,
+ CAL_JEWISH,
+ CAL_FRENCH,
+ CAL_NUM_CALS
+};
+typedef long int (*cal_to_jd_func_t)(int month, int day, int year);
+typedef void (*cal_from_jd_func_t)(long int jd, int* year, int* month, int* day);
+typedef char* (*cal_as_string_func_t)(int year, int month, int day);
+
+struct cal_entry_t {
+ char * name;
+ char * symbol;
+ cal_to_jd_func_t to_jd;
+ cal_from_jd_func_t from_jd;
+ int num_months;
+ int max_days_in_month;
+ char ** month_name_short;
+ char ** month_name_long;
+};
+static struct cal_entry_t cal_conversion_table[CAL_NUM_CALS] = {
+ { "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 }
+};
+
+/* For jddayofweek */
+enum { CAL_DOW_DAYNO, CAL_DOW_SHORT, CAL_DOW_LONG };
+/* 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 };
+
PHP_MINIT_FUNCTION(calendar)
{
- /*
- REGISTER_INT_CONSTANT("CAL_EASTER_TO_xxx",0, CONST_CS | CONST_PERSISTENT);
- */
- return SUCCESS;
+ REGISTER_LONG_CONSTANT("CAL_GREGORIAN", CAL_GREGORIAN, CONST_CS|CONST_PERSISTENT);
+ 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_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);
+ REGISTER_LONG_CONSTANT("CAL_DOW_SHORT", CAL_DOW_SHORT, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("CAL_DOW_LONG", CAL_DOW_LONG, CONST_CS|CONST_PERSISTENT);
+ /* constants for jdmonthname */
+ REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_SHORT", CAL_MONTH_GREGORIAN_SHORT, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_LONG", CAL_MONTH_GREGORIAN_LONG, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_SHORT", CAL_MONTH_JULIAN_SHORT, CONST_CS|CONST_PERSISTENT);
+ 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);
+
+ return SUCCESS;
}
PHP_MINFO_FUNCTION(calendar)
@@ -77,6 +132,152 @@ PHP_MINFO_FUNCTION(calendar)
php_info_print_table_end();
}
+/* {{{ proto array cal_info(int calendar)
+ * Return information about a particular calendar */
+PHP_FUNCTION(cal_info)
+{
+ zval ** cal;
+ zval * months, *smonths;
+ int i;
+ struct cal_entry_t * calendar;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cal) != SUCCESS) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long_ex(cal);
+ if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
+ zend_error(E_WARNING, "%s(): invalid calendar ID %d", get_active_function_name(), Z_LVAL_PP(cal));
+ RETURN_FALSE;
+ }
+
+ calendar = &cal_conversion_table[Z_LVAL_PP(cal)];
+ array_init(return_value);
+
+ MAKE_STD_ZVAL(months);
+ MAKE_STD_ZVAL(smonths);
+ array_init(months);
+ array_init(smonths);
+
+ for (i=1; i<= calendar->num_months; i++) {
+ add_index_string(months, i, calendar->month_name_long[i], 1);
+ add_index_string(smonths, i, calendar->month_name_short[i], 1);
+ }
+ add_assoc_zval(return_value, "months", months);
+ add_assoc_zval(return_value, "abbrevmonths", smonths);
+ add_assoc_long(return_value, "maxdaysinmonth", calendar->max_days_in_month);
+ add_assoc_string(return_value, "calname", calendar->name, 1);
+ add_assoc_string(return_value, "calsymbol", calendar->symbol, 1);
+
+}
+/* }}} */
+
+/* {{{ proto int cal_days_in_month(int calendar, int month, int year)
+ * Returns the number of days in a month for a given year and calendar */
+PHP_FUNCTION(cal_days_in_month)
+{
+ zval ** cal, **month, **year;
+ struct cal_entry_t * calendar;
+ long sdn_start, sdn_next;
+
+ if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &cal, &month, &year) != SUCCESS) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(cal);
+ convert_to_long_ex(month);
+ convert_to_long_ex(year);
+
+ if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
+ zend_error(E_WARNING, "%s(): invalid calendar ID %d", get_active_function_name(), Z_LVAL_PP(cal));
+ RETURN_FALSE;
+ }
+
+ calendar = &cal_conversion_table[Z_LVAL_PP(cal)];
+
+ sdn_start = calendar->to_jd(Z_LVAL_PP(year), Z_LVAL_PP(month), 1);
+
+ sdn_next = calendar->to_jd(Z_LVAL_PP(year), 1 + Z_LVAL_PP(month), 1);
+
+ if (sdn_next == 0) {
+ /* if invalid, try first month of the next year... */
+ sdn_next = calendar->to_jd(Z_LVAL_PP(year) + 1, 1, 1);
+ }
+
+ RETURN_LONG(sdn_next - sdn_start);
+}
+/* }}} */
+
+/* {{{ proto int cal_to_jd(int calendar, int month, int day, int year)
+ * Convert from a supported calendar to Julian Day Count */
+PHP_FUNCTION(cal_to_jd)
+{
+ zval ** cal, **month, **day, **year;
+ long jdate;
+
+ if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &cal, &month, &day, &year) != SUCCESS) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(cal);
+ convert_to_long_ex(month);
+ convert_to_long_ex(day);
+ convert_to_long_ex(year);
+
+ if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
+ zend_error(E_WARNING, "%s(): invalid calendar ID %d", get_active_function_name(), Z_LVAL_PP(cal));
+ RETURN_FALSE;
+ }
+
+ jdate = cal_conversion_table[Z_LVAL_PP(cal)].to_jd(
+ Z_LVAL_PP(year), Z_LVAL_PP(month), Z_LVAL_PP(day));
+ RETURN_LONG(jdate);
+}
+/* }}} */
+
+/* {{{ proto array cal_from_jd(int jd, int calendar)
+ * Convert from Julian Day Count to a supported calendar and return extended information */
+PHP_FUNCTION(cal_from_jd)
+{
+ zval ** jd, ** cal;
+ int month, day, year, dow;
+ char date[16];
+ struct cal_entry_t * calendar;
+
+ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &jd, &cal) != SUCCESS) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long_ex(jd);
+ convert_to_long_ex(cal);
+
+ if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
+ zend_error(E_WARNING, "%s(): invalid calendar ID %d", get_active_function_name(), Z_LVAL_PP(cal));
+ RETURN_FALSE;
+ }
+ calendar = &cal_conversion_table[Z_LVAL_PP(cal)];
+
+ array_init(return_value);
+
+ calendar->from_jd(
+ Z_LVAL_PP(jd),
+ &year, &month, &day);
+
+ sprintf(date, "%i/%i/%i", month, day, year);
+ add_assoc_string(return_value, "date", date, 1);
+
+ add_assoc_long(return_value, "month", month);
+ add_assoc_long(return_value, "day", day);
+ add_assoc_long(return_value, "year", year);
+
+ /* day of week */
+ dow = DayOfWeek(Z_LVAL_PP(jd));
+ add_assoc_long(return_value, "dow", dow);
+ add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow], 1);
+ add_assoc_string(return_value, "dayname", DayNameLong[dow], 1);
+ /* month name */
+ add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month], 1);
+ add_assoc_string(return_value, "monthname", calendar->month_name_long[month], 1);
+}
+/* }}} */
/* {{{ proto string jdtogregorian(int juliandaycount)
Convert a julian day count to a gregorian calendar date */
@@ -139,7 +340,6 @@ PHP_FUNCTION(jdtogregorian)
}
/* }}} */
-
/* {{{ proto int juliantojd(int month, int day, int year)
Convert a julian calendar date to julian day count */
PHP_FUNCTION(juliantojd)
@@ -161,7 +361,6 @@ PHP_FUNCTION(jdtogregorian)
}
/* }}} */
-
/* {{{ proto string jdtojewish(int juliandaycount)
Convert a julian day count to a jewish calendar date */
PHP_FUNCTION(jdtojewish)
@@ -183,7 +382,6 @@ PHP_FUNCTION(jdtogregorian)
}
/* }}} */
-
/* {{{ proto int jewishtojd(int month, int day, int year)
Convert a jewish calendar date to a julian day count */
PHP_FUNCTION(jewishtojd)
@@ -205,7 +403,6 @@ PHP_FUNCTION(jdtogregorian)
}
/* }}} */
-
/* {{{ proto string jdtofrench(int juliandaycount)
Convert a julian day count to a french republic calendar date */
PHP_FUNCTION(jdtofrench)
@@ -227,7 +424,6 @@ PHP_FUNCTION(jdtogregorian)
}
/* }}} */
-
/* {{{ proto int frenchtojd(int month, int day, int year)
Convert a french republic calendar date to julian day count */
PHP_FUNCTION(frenchtojd)
@@ -273,15 +469,13 @@ PHP_FUNCTION(jdtogregorian)
daynames = DayNameShort[day];
switch (mymode) {
- case 0L:
- RETURN_LONG(day);
- break;
- case 1L:
+ case CAL_DOW_SHORT:
RETURN_STRING(daynamel,1);
break;
- case 2L:
+ case CAL_DOW_LONG:
RETURN_STRING(daynames,1);
break;
+ case CAL_DOW_DAYNO:
default:
RETURN_LONG(day);
break;
@@ -300,39 +494,37 @@ PHP_FUNCTION(jdtogregorian)
if (zend_get_parameters_ex(2, &julday, &mode) != SUCCESS) {
WRONG_PARAM_COUNT;
}
-
+
convert_to_long_ex(julday);
convert_to_long_ex(mode);
- switch((*mode)->value.lval) {
- case 0L: /* gregorian or julian month */
- SdnToGregorian((*julday)->value.lval,&year, &month, &day);
- monthname = MonthNameShort[month];
- break;
- case 1L: /* gregorian or julian month */
- SdnToGregorian((*julday)->value.lval,&year, &month, &day);
- monthname = MonthNameLong[month];
- break;
- case 2L: /* gregorian or julian month */
- SdnToJulian((*julday)->value.lval, &year,&month, &day);
- monthname = MonthNameShort[month];
- break;
- case 3L: /* gregorian or julian month */
- SdnToJulian((*julday)->value.lval, &year,&month, &day);
- monthname = MonthNameLong[month];
- break;
- case 4L: /* jewish month */
- SdnToJewish((*julday)->value.lval, &year,&month, &day);
- monthname = JewishMonthName[month];
- break;
- case 5L: /* french month */
- SdnToFrench((*julday)->value.lval, &year,&month, &day);
- monthname = FrenchMonthName[month];
- break;
- default: /* default gregorian */
- /* FIXME - need to set monthname to something here ?? */
- break;
- }
+ switch((*mode)->value.lval) {
+ case CAL_MONTH_GREGORIAN_LONG: /* gregorian or julian month */
+ SdnToGregorian((*julday)->value.lval,&year, &month, &day);
+ monthname = MonthNameLong[month];
+ break;
+ case CAL_MONTH_JULIAN_SHORT: /* gregorian or julian month */
+ SdnToJulian((*julday)->value.lval, &year,&month, &day);
+ monthname = MonthNameShort[month];
+ break;
+ case CAL_MONTH_JULIAN_LONG: /* gregorian or julian month */
+ SdnToJulian((*julday)->value.lval, &year,&month, &day);
+ monthname = MonthNameLong[month];
+ break;
+ case CAL_MONTH_JEWISH: /* jewish month */
+ SdnToJewish((*julday)->value.lval, &year,&month, &day);
+ monthname = JewishMonthName[month];
+ break;
+ case CAL_MONTH_FRENCH: /* french month */
+ SdnToFrench((*julday)->value.lval, &year,&month, &day);
+ monthname = FrenchMonthName[month];
+ break;
+ default: /* default gregorian */
+ case CAL_MONTH_GREGORIAN_SHORT: /* gregorian or julian month */
+ SdnToGregorian((*julday)->value.lval,&year, &month, &day);
+ monthname = MonthNameShort[month];
+ break;
+ }
RETURN_STRING(monthname,1);
}
diff --git a/ext/calendar/php_calendar.h b/ext/calendar/php_calendar.h
index d56d3af19a..73bc96aede 100644
--- a/ext/calendar/php_calendar.h
+++ b/ext/calendar/php_calendar.h
@@ -25,7 +25,10 @@ PHP_FUNCTION(easter_days);
PHP_FUNCTION(easter_date);
PHP_FUNCTION(unixtojd);
PHP_FUNCTION(jdtounix);
-
+PHP_FUNCTION(cal_from_jd);
+PHP_FUNCTION(cal_to_jd);
+PHP_FUNCTION(cal_days_in_month);
+PHP_FUNCTION(cal_info);
#define phpext_calendar_ptr calendar_module_ptr