root/ext/calendar/calendar.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ZEND_GET_MODULE
  2. PHP_MINIT_FUNCTION
  3. PHP_MINFO_FUNCTION
  4. _php_cal_info
  5. PHP_FUNCTION
  6. PHP_FUNCTION
  7. PHP_FUNCTION
  8. PHP_FUNCTION
  9. PHP_FUNCTION
  10. PHP_FUNCTION
  11. PHP_FUNCTION
  12. PHP_FUNCTION
  13. heb_number_to_chars
  14. PHP_FUNCTION
  15. PHP_FUNCTION
  16. PHP_FUNCTION
  17. PHP_FUNCTION
  18. PHP_FUNCTION
  19. PHP_FUNCTION

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Authors: Shane Caraveo             <shane@caraveo.com>               | 
  16    |          Colin Viebrock            <colin@easydns.com>               |
  17    |          Hartmut Holzgraefe        <hholzgra@php.net>                |
  18    |          Wez Furlong               <wez@thebrainroom.com>            |
  19    +----------------------------------------------------------------------+
  20  */
  21 /* $Id$ */
  22 
  23 #ifdef HAVE_CONFIG_H
  24 #include "config.h"
  25 #endif
  26 
  27 #ifdef PHP_WIN32
  28 #define _WINNLS_
  29 #endif
  30 
  31 #include "php.h"
  32 #include "ext/standard/info.h"
  33 #include "php_calendar.h"
  34 #include "sdncal.h"
  35 
  36 #include <stdio.h>
  37 
  38 /* {{{ arginfo */
  39 ZEND_BEGIN_ARG_INFO_EX(arginfo_unixtojd, 0, 0, 0)
  40         ZEND_ARG_INFO(0, timestamp)
  41 ZEND_END_ARG_INFO()
  42 
  43 ZEND_BEGIN_ARG_INFO(arginfo_jdtounix, 0)
  44         ZEND_ARG_INFO(0, jday)
  45 ZEND_END_ARG_INFO()
  46 
  47 ZEND_BEGIN_ARG_INFO_EX(arginfo_cal_info, 0, 0, 0)
  48         ZEND_ARG_INFO(0, calendar)
  49 ZEND_END_ARG_INFO()
  50 
  51 ZEND_BEGIN_ARG_INFO(arginfo_cal_days_in_month, 0)
  52         ZEND_ARG_INFO(0, calendar)
  53         ZEND_ARG_INFO(0, month)
  54         ZEND_ARG_INFO(0, year)
  55 ZEND_END_ARG_INFO()
  56 
  57 ZEND_BEGIN_ARG_INFO(arginfo_cal_to_jd, 0)
  58         ZEND_ARG_INFO(0, calendar)
  59         ZEND_ARG_INFO(0, month)
  60         ZEND_ARG_INFO(0, day)
  61         ZEND_ARG_INFO(0, year)
  62 ZEND_END_ARG_INFO()
  63 
  64 ZEND_BEGIN_ARG_INFO(arginfo_cal_from_jd, 0)
  65         ZEND_ARG_INFO(0, jd)
  66         ZEND_ARG_INFO(0, calendar)
  67 ZEND_END_ARG_INFO()
  68 
  69 ZEND_BEGIN_ARG_INFO(arginfo_jdtogregorian, 0)
  70         ZEND_ARG_INFO(0, juliandaycount)
  71 ZEND_END_ARG_INFO()
  72 
  73 ZEND_BEGIN_ARG_INFO(arginfo_gregoriantojd, 0)
  74         ZEND_ARG_INFO(0, month)
  75         ZEND_ARG_INFO(0, day)
  76         ZEND_ARG_INFO(0, year)
  77 ZEND_END_ARG_INFO()
  78 
  79 ZEND_BEGIN_ARG_INFO(arginfo_jdtojulian, 0)
  80         ZEND_ARG_INFO(0, juliandaycount)
  81 ZEND_END_ARG_INFO()
  82 
  83 ZEND_BEGIN_ARG_INFO(arginfo_juliantojd, 0)
  84         ZEND_ARG_INFO(0, month)
  85         ZEND_ARG_INFO(0, day)
  86         ZEND_ARG_INFO(0, year)
  87 ZEND_END_ARG_INFO()
  88 
  89 ZEND_BEGIN_ARG_INFO_EX(arginfo_jdtojewish, 0, 0, 1)
  90         ZEND_ARG_INFO(0, juliandaycount)
  91         ZEND_ARG_INFO(0, hebrew)
  92         ZEND_ARG_INFO(0, fl)
  93 ZEND_END_ARG_INFO()
  94 
  95 ZEND_BEGIN_ARG_INFO(arginfo_jewishtojd, 0)
  96         ZEND_ARG_INFO(0, month)
  97         ZEND_ARG_INFO(0, day)
  98         ZEND_ARG_INFO(0, year)
  99 ZEND_END_ARG_INFO()
 100 
 101 ZEND_BEGIN_ARG_INFO(arginfo_jdtofrench, 0)
 102         ZEND_ARG_INFO(0, juliandaycount)
 103 ZEND_END_ARG_INFO()
 104 
 105 ZEND_BEGIN_ARG_INFO(arginfo_frenchtojd, 0)
 106         ZEND_ARG_INFO(0, month)
 107         ZEND_ARG_INFO(0, day)
 108         ZEND_ARG_INFO(0, year)
 109 ZEND_END_ARG_INFO()
 110 
 111 ZEND_BEGIN_ARG_INFO_EX(arginfo_jddayofweek, 0, 0, 1)
 112         ZEND_ARG_INFO(0, juliandaycount)
 113         ZEND_ARG_INFO(0, mode)
 114 ZEND_END_ARG_INFO()
 115 
 116 ZEND_BEGIN_ARG_INFO(arginfo_jdmonthname, 0)
 117         ZEND_ARG_INFO(0, juliandaycount)
 118         ZEND_ARG_INFO(0, mode)
 119 ZEND_END_ARG_INFO()
 120 
 121 ZEND_BEGIN_ARG_INFO_EX(arginfo_easter_date, 0, 0, 0)
 122         ZEND_ARG_INFO(0, year)
 123 ZEND_END_ARG_INFO()
 124 
 125 ZEND_BEGIN_ARG_INFO_EX(arginfo_easter_days, 0, 0, 0)
 126         ZEND_ARG_INFO(0, year)
 127         ZEND_ARG_INFO(0, method)
 128 ZEND_END_ARG_INFO()
 129 
 130 /* }}} */
 131 
 132 const zend_function_entry calendar_functions[] = {
 133         PHP_FE(jdtogregorian, arginfo_jdtogregorian)
 134         PHP_FE(gregoriantojd, arginfo_gregoriantojd)
 135         PHP_FE(jdtojulian, arginfo_jdtojulian)
 136         PHP_FE(juliantojd, arginfo_juliantojd)
 137         PHP_FE(jdtojewish, arginfo_jdtojewish)
 138         PHP_FE(jewishtojd, arginfo_jewishtojd)
 139         PHP_FE(jdtofrench, arginfo_jdtofrench)
 140         PHP_FE(frenchtojd, arginfo_frenchtojd)
 141         PHP_FE(jddayofweek, arginfo_jddayofweek)
 142         PHP_FE(jdmonthname, arginfo_jdmonthname)
 143         PHP_FE(easter_date, arginfo_easter_date)
 144         PHP_FE(easter_days, arginfo_easter_days)
 145         PHP_FE(unixtojd, arginfo_unixtojd)
 146         PHP_FE(jdtounix, arginfo_jdtounix)
 147         PHP_FE(cal_to_jd, arginfo_cal_to_jd)
 148         PHP_FE(cal_from_jd, arginfo_cal_from_jd)
 149         PHP_FE(cal_days_in_month, arginfo_cal_days_in_month)
 150         PHP_FE(cal_info, arginfo_cal_info)
 151         PHP_FE_END
 152 };
 153 
 154 
 155 zend_module_entry calendar_module_entry = {
 156         STANDARD_MODULE_HEADER,
 157         "calendar",
 158         calendar_functions,
 159         PHP_MINIT(calendar),
 160         NULL,
 161         NULL,
 162         NULL,
 163         PHP_MINFO(calendar),
 164         NO_VERSION_YET,
 165         STANDARD_MODULE_PROPERTIES,
 166 };
 167 
 168 #ifdef COMPILE_DL_CALENDAR
 169 ZEND_GET_MODULE(calendar)
 170 #endif
 171 
 172 /* this order must match the conversion table below */
 173 enum cal_name_type_t {
 174         CAL_GREGORIAN = 0,
 175         CAL_JULIAN,
 176         CAL_JEWISH,
 177         CAL_FRENCH,
 178         CAL_NUM_CALS
 179 };
 180 
 181 typedef long int (*cal_to_jd_func_t) (int month, int day, int year);
 182 typedef void (*cal_from_jd_func_t) (long int jd, int *year, int *month, int *day);
 183 typedef char *(*cal_as_string_func_t) (int year, int month, int day);
 184 
 185 struct cal_entry_t {
 186         char *name;
 187         char *symbol;
 188         cal_to_jd_func_t to_jd;
 189         cal_from_jd_func_t from_jd;
 190         int num_months;
 191         int max_days_in_month;
 192         char **month_name_short;
 193         char **month_name_long;
 194 };
 195 
 196 static struct cal_entry_t cal_conversion_table[CAL_NUM_CALS] = {
 197         {"Gregorian", "CAL_GREGORIAN", GregorianToSdn, SdnToGregorian, 12, 31,
 198          MonthNameShort, MonthNameLong},
 199         {"Julian", "CAL_JULIAN", JulianToSdn, SdnToJulian, 12, 31,
 200          MonthNameShort, MonthNameLong},
 201         {"Jewish", "CAL_JEWISH", JewishToSdn, SdnToJewish, 13, 30,
 202          JewishMonthNameLeap, JewishMonthNameLeap},
 203         {"French", "CAL_FRENCH", FrenchToSdn, SdnToFrench, 13, 30,
 204          FrenchMonthName, FrenchMonthName}
 205 };
 206 
 207 #define JEWISH_MONTH_NAME(year)         ((monthsPerYear[((year)-1) % 19] == 13)?JewishMonthNameLeap:JewishMonthName)
 208 #define JEWISH_HEB_MONTH_NAME(year) ((monthsPerYear[((year)-1) % 19] == 13)?JewishMonthHebNameLeap:JewishMonthHebName)
 209 
 210 /* For jddayofweek */
 211 enum { CAL_DOW_DAYNO, CAL_DOW_LONG, CAL_DOW_SHORT };
 212 
 213 /* For jdmonthname */
 214 enum { CAL_MONTH_GREGORIAN_SHORT, CAL_MONTH_GREGORIAN_LONG,
 215         CAL_MONTH_JULIAN_SHORT, CAL_MONTH_JULIAN_LONG, CAL_MONTH_JEWISH,
 216         CAL_MONTH_FRENCH
 217 };
 218 
 219 /* for heb_number_to_chars */
 220 static char alef_bet[25] = "0אבגדהוזחטיכלמנסעפצקרשת";
 221 
 222 #define CAL_JEWISH_ADD_ALAFIM_GERESH 0x2
 223 #define CAL_JEWISH_ADD_ALAFIM 0x4
 224 #define CAL_JEWISH_ADD_GERESHAYIM 0x8
 225 
 226 PHP_MINIT_FUNCTION(calendar)
 227 {
 228         REGISTER_LONG_CONSTANT("CAL_GREGORIAN", CAL_GREGORIAN, CONST_CS | CONST_PERSISTENT);
 229         REGISTER_LONG_CONSTANT("CAL_JULIAN", CAL_JULIAN, CONST_CS | CONST_PERSISTENT);
 230         REGISTER_LONG_CONSTANT("CAL_JEWISH", CAL_JEWISH, CONST_CS | CONST_PERSISTENT);
 231         REGISTER_LONG_CONSTANT("CAL_FRENCH", CAL_FRENCH, CONST_CS | CONST_PERSISTENT);
 232         REGISTER_LONG_CONSTANT("CAL_NUM_CALS", CAL_NUM_CALS, CONST_CS | CONST_PERSISTENT);
 233 /* constants for jddayofweek */
 234         REGISTER_LONG_CONSTANT("CAL_DOW_DAYNO", CAL_DOW_DAYNO, CONST_CS | CONST_PERSISTENT);
 235         REGISTER_LONG_CONSTANT("CAL_DOW_SHORT", CAL_DOW_SHORT, CONST_CS | CONST_PERSISTENT);
 236         REGISTER_LONG_CONSTANT("CAL_DOW_LONG", CAL_DOW_LONG, CONST_CS | CONST_PERSISTENT);
 237 /* constants for jdmonthname */
 238         REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_SHORT", CAL_MONTH_GREGORIAN_SHORT, CONST_CS | CONST_PERSISTENT);
 239         REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_LONG", CAL_MONTH_GREGORIAN_LONG, CONST_CS | CONST_PERSISTENT);
 240         REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_SHORT", CAL_MONTH_JULIAN_SHORT, CONST_CS | CONST_PERSISTENT);
 241         REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_LONG", CAL_MONTH_JULIAN_LONG, CONST_CS | CONST_PERSISTENT);
 242         REGISTER_LONG_CONSTANT("CAL_MONTH_JEWISH", CAL_MONTH_JEWISH, CONST_CS | CONST_PERSISTENT);
 243         REGISTER_LONG_CONSTANT("CAL_MONTH_FRENCH", CAL_MONTH_FRENCH, CONST_CS | CONST_PERSISTENT);
 244 /* constants for easter calculation */
 245         REGISTER_LONG_CONSTANT("CAL_EASTER_DEFAULT", CAL_EASTER_DEFAULT, CONST_CS | CONST_PERSISTENT);
 246         REGISTER_LONG_CONSTANT("CAL_EASTER_ROMAN", CAL_EASTER_ROMAN, CONST_CS | CONST_PERSISTENT);
 247         REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_GREGORIAN", CAL_EASTER_ALWAYS_GREGORIAN, CONST_CS | CONST_PERSISTENT);
 248         REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_JULIAN", CAL_EASTER_ALWAYS_JULIAN, CONST_CS | CONST_PERSISTENT);
 249 /* constants for Jewish date formatting */
 250         REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_ALAFIM_GERESH", CAL_JEWISH_ADD_ALAFIM_GERESH, CONST_CS | CONST_PERSISTENT);
 251         REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_ALAFIM", CAL_JEWISH_ADD_ALAFIM, CONST_CS | CONST_PERSISTENT);
 252         REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_GERESHAYIM", CAL_JEWISH_ADD_GERESHAYIM, CONST_CS | CONST_PERSISTENT);
 253         return SUCCESS;
 254 }
 255 
 256 PHP_MINFO_FUNCTION(calendar)
 257 {
 258         php_info_print_table_start();
 259         php_info_print_table_row(2, "Calendar support", "enabled");
 260         php_info_print_table_end();
 261 }
 262 
 263 static void _php_cal_info(int cal, zval **ret)
 264 {
 265         zval *months, *smonths;
 266         int i;
 267         struct cal_entry_t *calendar;
 268 
 269         calendar = &cal_conversion_table[cal];
 270         array_init(*ret);
 271 
 272         MAKE_STD_ZVAL(months);
 273         MAKE_STD_ZVAL(smonths);
 274         array_init(months);
 275         array_init(smonths);
 276 
 277         for (i = 1; i <= calendar->num_months; i++) {
 278                 add_index_string(months, i, calendar->month_name_long[i], 1);
 279                 add_index_string(smonths, i, calendar->month_name_short[i], 1);
 280         }
 281         add_assoc_zval(*ret, "months", months);
 282         add_assoc_zval(*ret, "abbrevmonths", smonths);
 283         add_assoc_long(*ret, "maxdaysinmonth", calendar->max_days_in_month);
 284         add_assoc_string(*ret, "calname", calendar->name, 1);
 285         add_assoc_string(*ret, "calsymbol", calendar->symbol, 1);
 286         
 287 }
 288 
 289 /* {{{ proto array cal_info([int calendar])
 290    Returns information about a particular calendar */
 291 PHP_FUNCTION(cal_info)
 292 {
 293         long cal = -1;
 294 
 295 
 296         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &cal) == FAILURE) {
 297                 RETURN_FALSE;
 298         }
 299 
 300         if (cal == -1) {
 301                 int i;
 302                 zval *val;
 303 
 304                 array_init(return_value);
 305 
 306                 for (i = 0; i < CAL_NUM_CALS; i++) {
 307                         MAKE_STD_ZVAL(val);
 308                         _php_cal_info(i, &val);
 309                         add_index_zval(return_value, i, val);
 310                 }
 311                 return;
 312         }
 313 
 314 
 315         if (cal != -1 && (cal < 0 || cal >= CAL_NUM_CALS)) {
 316                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld.", cal);
 317                 RETURN_FALSE;
 318         }
 319 
 320         _php_cal_info(cal, &return_value);
 321 
 322 }
 323 /* }}} */
 324 
 325 /* {{{ proto int cal_days_in_month(int calendar, int month, int year)
 326    Returns the number of days in a month for a given year and calendar */
 327 PHP_FUNCTION(cal_days_in_month)
 328 {
 329         long cal, month, year;
 330         struct cal_entry_t *calendar;
 331         long sdn_start, sdn_next;
 332 
 333         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &cal, &month, &year) == FAILURE) {
 334                 RETURN_FALSE;
 335         }
 336 
 337         if (cal < 0 || cal >= CAL_NUM_CALS) {
 338                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld.", cal);
 339                 RETURN_FALSE;
 340         }
 341 
 342         calendar = &cal_conversion_table[cal];
 343 
 344         sdn_start = calendar->to_jd(year, month, 1);
 345 
 346         if (sdn_start == 0) {
 347                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid date.");
 348                 RETURN_FALSE;
 349         }
 350 
 351         sdn_next = calendar->to_jd(year, 1 + month, 1);
 352 
 353         if (sdn_next == 0) {
 354                 /* If the next month is invalid, then we need to try the first month of
 355                  * the next year, bearing in mind that the next year after 1 BCE is
 356                  * actually 1 AD and not 0. */
 357                 if (year == -1) {
 358                         sdn_next = calendar->to_jd(1, 1, 1);
 359                 }
 360                 else {
 361                         sdn_next = calendar->to_jd(year + 1, 1, 1);
 362                 }
 363         }
 364 
 365         RETURN_LONG(sdn_next - sdn_start);
 366 }
 367 /* }}} */
 368 
 369 /* {{{ proto int cal_to_jd(int calendar, int month, int day, int year)
 370    Converts from a supported calendar to Julian Day Count */
 371 PHP_FUNCTION(cal_to_jd)
 372 {
 373         long cal, month, day, year;
 374 
 375         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llll", &cal, &month, &day, &year) != SUCCESS) {
 376                 RETURN_FALSE;
 377         }
 378 
 379         if (cal < 0 || cal >= CAL_NUM_CALS) {
 380                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld.", cal);
 381                 RETURN_FALSE;
 382         }
 383 
 384         RETURN_LONG(cal_conversion_table[cal].to_jd(year, month, day));
 385 }
 386 /* }}} */
 387 
 388 /* {{{ proto array cal_from_jd(int jd, int calendar)
 389    Converts from Julian Day Count to a supported calendar and return extended information */
 390 PHP_FUNCTION(cal_from_jd)
 391 {
 392         long jd, cal;
 393         int month, day, year, dow;
 394         char date[16];
 395         struct cal_entry_t *calendar;
 396 
 397         if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "ll", &jd, &cal) == FAILURE) {
 398                 RETURN_FALSE;
 399         }
 400 
 401         if (cal < 0 || cal >= CAL_NUM_CALS) {
 402                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld", cal);
 403                 RETURN_FALSE;
 404         }
 405         calendar = &cal_conversion_table[cal];
 406 
 407         array_init(return_value);
 408 
 409         calendar->from_jd(jd, &year, &month, &day);
 410 
 411         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 412         add_assoc_string(return_value, "date", date, 1);
 413 
 414         add_assoc_long(return_value, "month", month);
 415         add_assoc_long(return_value, "day", day);
 416         add_assoc_long(return_value, "year", year);
 417 
 418 /* day of week */
 419         dow = DayOfWeek(jd);
 420         add_assoc_long(return_value, "dow", dow);
 421         add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow], 1);
 422         add_assoc_string(return_value, "dayname", DayNameLong[dow], 1);
 423 /* month name */
 424         if(cal == CAL_JEWISH) {
 425                 /* special case for Jewish calendar */
 426                 add_assoc_string(return_value, "abbrevmonth", JEWISH_MONTH_NAME(year)[month], 1);
 427                 add_assoc_string(return_value, "monthname", JEWISH_MONTH_NAME(year)[month], 1);
 428         } else {
 429                 add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month], 1);
 430                 add_assoc_string(return_value, "monthname", calendar->month_name_long[month], 1);
 431         }
 432 }
 433 /* }}} */
 434 
 435 /* {{{ proto string jdtogregorian(int juliandaycount)
 436    Converts a julian day count to a gregorian calendar date */
 437 PHP_FUNCTION(jdtogregorian)
 438 {
 439         long julday;
 440         int year, month, day;
 441         char date[16];
 442 
 443         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &julday) == FAILURE) {
 444                 RETURN_FALSE;
 445         }
 446 
 447         SdnToGregorian(julday, &year, &month, &day);
 448         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 449 
 450         RETURN_STRING(date, 1);
 451 }
 452 /* }}} */
 453 
 454 /* {{{ proto int gregoriantojd(int month, int day, int year)
 455    Converts a gregorian calendar date to julian day count */
 456 PHP_FUNCTION(gregoriantojd)
 457 {
 458         long year, month, day;
 459 
 460         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
 461                 RETURN_FALSE;
 462         }
 463 
 464         RETURN_LONG(GregorianToSdn(year, month, day));
 465 }
 466 /* }}} */
 467 
 468 /* {{{ proto string jdtojulian(int juliandaycount)
 469    Convert a julian day count to a julian calendar date */
 470 PHP_FUNCTION(jdtojulian)
 471 {
 472         long julday;
 473         int year, month, day;
 474         char date[16];
 475 
 476         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &julday) == FAILURE) {
 477                 RETURN_FALSE;
 478         }
 479 
 480         SdnToJulian(julday, &year, &month, &day);
 481         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 482 
 483         RETURN_STRING(date, 1);
 484 }
 485 /* }}} */
 486 
 487 /* {{{ proto int juliantojd(int month, int day, int year)
 488    Converts a julian calendar date to julian day count */
 489 PHP_FUNCTION(juliantojd)
 490 {
 491         long year, month, day;
 492 
 493         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
 494                 RETURN_FALSE;
 495         }
 496 
 497         RETURN_LONG(JulianToSdn(year, month, day));
 498 }
 499 /* }}} */
 500 
 501 /* {{{ heb_number_to_chars*/
 502 /*
 503 caution: the Hebrew format produces non unique result.
 504 for example both: year '5' and year '5000' produce 'ה'.
 505 use the numeric one for calculations. 
 506  */
 507 static char *heb_number_to_chars(int n, int fl, char **ret)
 508 {
 509         char *p, old[18], *endofalafim;
 510 
 511         p = endofalafim = old;
 512 /* 
 513    prevents the option breaking the jewish beliefs, and some other 
 514    critical resources ;)
 515  */
 516         if (n > 9999 || n < 1) {
 517                 *ret = NULL;
 518                 return NULL;
 519         }       
 520 
 521 /* alafim (thousands) case */
 522         if (n / 1000) {
 523                 *p = alef_bet[n / 1000];
 524                 p++;
 525 
 526                 if (CAL_JEWISH_ADD_ALAFIM_GERESH & fl) {
 527                         *p = '\'';
 528                         p++;
 529                 }
 530                 if (CAL_JEWISH_ADD_ALAFIM & fl) {
 531                         strcpy(p, " אלפים ");
 532                         p += 7;
 533                 }
 534 
 535                 endofalafim = p;
 536                 n = n % 1000;
 537         }
 538 
 539 /* tav-tav (tav=400) case */
 540         while (n >= 400) {
 541                 *p = alef_bet[22];
 542                 p++;
 543                 n -= 400;
 544         }
 545 
 546 /* meot (hundreads) case */
 547         if (n >= 100) {
 548                 *p = alef_bet[18 + n / 100];
 549                 p++;
 550                 n = n % 100;
 551         }
 552 
 553 /* tet-vav & tet-zain case (special case for 15 and 16) */
 554         if (n == 15 || n == 16) {
 555                 *p = alef_bet[9];
 556                 p++;
 557                 *p = alef_bet[n - 9];
 558                 p++;
 559         } else {
 560 /* asarot (tens) case */
 561                 if (n >= 10) {
 562                         *p = alef_bet[9 + n / 10];
 563                         p++;
 564                         n = n % 10;
 565                 }
 566 
 567 /* yehidot (ones) case */
 568                 if (n > 0) {
 569                         *p = alef_bet[n];
 570                         p++;
 571                 }
 572         }
 573 
 574         if (CAL_JEWISH_ADD_GERESHAYIM & fl) {
 575                 switch (p - endofalafim) {
 576                 case 0:
 577                         break;
 578                 case 1:
 579                         *p = '\'';
 580                         p++;
 581                         break;
 582                 default:
 583                         *(p) = *(p - 1);
 584                         *(p - 1) = '"';
 585                         p++;
 586                 }
 587         }
 588 
 589         *p = '\0';
 590         *ret = estrndup(old, (p - old) + 1);
 591         p = *ret;
 592         return p;
 593 }
 594 /* }}} */
 595 
 596 /* {{{ proto string jdtojewish(int juliandaycount [, bool hebrew [, int fl]])
 597    Converts a julian day count to a jewish calendar date */
 598 PHP_FUNCTION(jdtojewish)
 599 {
 600         long julday, fl = 0;
 601         zend_bool heb   = 0;
 602         int year, month, day;
 603         char date[16], hebdate[32];
 604         char *dayp, *yearp;
 605 
 606         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|bl", &julday, &heb, &fl) == FAILURE) {
 607                 RETURN_FALSE;
 608         }
 609 
 610         SdnToJewish(julday, &year, &month, &day);
 611         if (!heb) {
 612                 snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 613                 RETURN_STRING(date, 1);
 614         } else {
 615                 if (year <= 0 || year > 9999) {
 616                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Year out of range (0-9999).");
 617                         RETURN_FALSE;
 618                 }
 619 
 620                 snprintf(hebdate, sizeof(hebdate), "%s %s %s", heb_number_to_chars(day, fl, &dayp), JEWISH_HEB_MONTH_NAME(year)[month], heb_number_to_chars(year, fl, &yearp));
 621 
 622                 if (dayp) {
 623                         efree(dayp);
 624                 }
 625                 if (yearp) {
 626                         efree(yearp);
 627                 }
 628 
 629                 RETURN_STRING(hebdate, 1);
 630 
 631         }
 632 }
 633 /* }}} */
 634 
 635 /* {{{ proto int jewishtojd(int month, int day, int year)
 636    Converts a jewish calendar date to a julian day count */
 637 PHP_FUNCTION(jewishtojd)
 638 {
 639         long year, month, day;
 640 
 641         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
 642                 RETURN_FALSE;
 643         }
 644 
 645         RETURN_LONG(JewishToSdn(year, month, day));
 646 }
 647 /* }}} */
 648 
 649 /* {{{ proto string jdtofrench(int juliandaycount)
 650    Converts a julian day count to a french republic calendar date */
 651 PHP_FUNCTION(jdtofrench)
 652 {
 653         long julday;
 654         int year, month, day;
 655         char date[16];
 656 
 657         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &julday) == FAILURE) {
 658                 RETURN_FALSE;
 659         }
 660 
 661         SdnToFrench(julday, &year, &month, &day);
 662         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 663 
 664         RETURN_STRING(date, 1);
 665 }
 666 /* }}} */
 667 
 668 /* {{{ proto int frenchtojd(int month, int day, int year)
 669    Converts a french republic calendar date to julian day count */
 670 PHP_FUNCTION(frenchtojd)
 671 {
 672         long year, month, day;
 673 
 674         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
 675                 RETURN_FALSE;
 676         }
 677 
 678         RETURN_LONG(FrenchToSdn(year, month, day));
 679 }
 680 /* }}} */
 681 
 682 /* {{{ proto mixed jddayofweek(int juliandaycount [, int mode])
 683    Returns name or number of day of week from julian day count */
 684 PHP_FUNCTION(jddayofweek)
 685 {
 686         long julday, mode = CAL_DOW_DAYNO;
 687         int day;
 688         char *daynamel, *daynames;
 689 
 690         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &julday, &mode) == FAILURE) {
 691                 RETURN_FALSE;
 692         }
 693 
 694         day = DayOfWeek(julday);
 695         daynamel = DayNameLong[day];
 696         daynames = DayNameShort[day];
 697 
 698         switch (mode) {
 699         case CAL_DOW_LONG:
 700                 RETURN_STRING(daynamel, 1);
 701                 break;
 702         case CAL_DOW_SHORT:
 703                 RETURN_STRING(daynames, 1);
 704                 break;
 705         case CAL_DOW_DAYNO:
 706         default:
 707                 RETURN_LONG(day);
 708                 break;
 709         }
 710 }
 711 /* }}} */
 712 
 713 /* {{{ proto string jdmonthname(int juliandaycount, int mode)
 714    Returns name of month for julian day count */
 715 PHP_FUNCTION(jdmonthname)
 716 {
 717         long julday, mode;
 718         char *monthname = NULL;
 719         int month, day, year;
 720 
 721         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &julday, &mode) == FAILURE) {
 722                 RETURN_FALSE;
 723         }
 724 
 725         switch (mode) {
 726         case CAL_MONTH_GREGORIAN_LONG:  /* gregorian or julian month */
 727                 SdnToGregorian(julday, &year, &month, &day);
 728                 monthname = MonthNameLong[month];
 729                 break;
 730         case CAL_MONTH_JULIAN_SHORT:    /* gregorian or julian month */
 731                 SdnToJulian(julday, &year, &month, &day);
 732                 monthname = MonthNameShort[month];
 733                 break;
 734         case CAL_MONTH_JULIAN_LONG:     /* gregorian or julian month */
 735                 SdnToJulian(julday, &year, &month, &day);
 736                 monthname = MonthNameLong[month];
 737                 break;
 738         case CAL_MONTH_JEWISH:          /* jewish month */
 739                 SdnToJewish(julday, &year, &month, &day);
 740                 monthname = JEWISH_MONTH_NAME(year)[month];
 741                 break;
 742         case CAL_MONTH_FRENCH:          /* french month */
 743                 SdnToFrench(julday, &year, &month, &day);
 744                 monthname = FrenchMonthName[month];
 745                 break;
 746         default:                                        /* default gregorian */
 747         case CAL_MONTH_GREGORIAN_SHORT: /* gregorian or julian month */
 748                 SdnToGregorian(julday, &year, &month, &day);
 749                 monthname = MonthNameShort[month];
 750                 break;
 751         }
 752 
 753         RETURN_STRING(monthname, 1);
 754 }
 755 /* }}} */
 756 
 757 /*
 758  * Local variables:
 759  * tab-width: 4
 760  * c-basic-offset: 4
 761  * End:
 762  * vim600: sw=4 ts=4 fdm=marker
 763  * vim<600: sw=4 ts=4
 764  */

/* [<][>][^][v][top][bottom][index][help] */