]> granicus.if.org Git - php/commitdiff
Added a couple of new functions to "modularize" working with calendars.
authorWez Furlong <wez@php.net>
Wed, 4 Jul 2001 10:12:45 +0000 (10:12 +0000)
committerWez Furlong <wez@php.net>
Wed, 4 Jul 2001 10:12:45 +0000 (10:12 +0000)
Added a few constants for the existing functions, and tidied them up a bit.

ext/calendar/CREDITS
ext/calendar/calendar.c
ext/calendar/php_calendar.h

index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a2904bd8b21eb28c5727735f68f53322ae54a8a8 100644 (file)
@@ -0,0 +1,2 @@
+Calendar
+Shane Caraveo, Colin Viebrock, Hartmut Holzgraefe, Wez Furlong
index 12ae1aae67158dfc5b1dd155cdfbf78ff0014f46..7c06d393fb6b6d1bab9c2f2ed740ab826d7a9b14 100644 (file)
    | 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);
 }
index d56d3af19ab6e28dadebf3d891ad97f571970f3b..73bc96aede6db4c9da664fc09462fd515ac2c787 100644 (file)
@@ -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