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 7                                                        |
   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         PHP_CALENDAR_VERSION,
 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 zend_long (*cal_to_jd_func_t) (int month, int day, int year);
 182 typedef void (*cal_from_jd_func_t) (zend_long 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         array_init(&months);
 273         array_init(&smonths);
 274 
 275         for (i = 1; i <= calendar->num_months; i++) {
 276                 add_index_string(&months, i, calendar->month_name_long[i]);
 277                 add_index_string(&smonths, i, calendar->month_name_short[i]);
 278         }
 279         
 280         add_assoc_zval(ret, "months", &months);
 281         add_assoc_zval(ret, "abbrevmonths", &smonths);
 282         add_assoc_long(ret, "maxdaysinmonth", calendar->max_days_in_month);
 283         add_assoc_string(ret, "calname", calendar->name);
 284         add_assoc_string(ret, "calsymbol", calendar->symbol);
 285         
 286 }
 287 
 288 /* {{{ proto array cal_info([int calendar])
 289    Returns information about a particular calendar */
 290 PHP_FUNCTION(cal_info)
 291 {
 292         zend_long cal = -1;
 293 
 294 
 295         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &cal) == FAILURE) {
 296                 RETURN_FALSE;
 297         }
 298 
 299         if (cal == -1) {
 300                 int i;
 301                 zval val;
 302 
 303                 array_init(return_value);
 304 
 305                 for (i = 0; i < CAL_NUM_CALS; i++) {
 306                         _php_cal_info(i, &val);
 307                         add_index_zval(return_value, i, &val);
 308                 }
 309                 return;
 310         }
 311 
 312 
 313         if (cal != -1 && (cal < 0 || cal >= CAL_NUM_CALS)) {
 314                 php_error_docref(NULL, E_WARNING, "invalid calendar ID %pd.", cal);
 315                 RETURN_FALSE;
 316         }
 317 
 318         _php_cal_info(cal, return_value);
 319 
 320 }
 321 /* }}} */
 322 
 323 /* {{{ proto int cal_days_in_month(int calendar, int month, int year)
 324    Returns the number of days in a month for a given year and calendar */
 325 PHP_FUNCTION(cal_days_in_month)
 326 {
 327         zend_long cal, month, year;
 328         struct cal_entry_t *calendar;
 329         zend_long sdn_start, sdn_next;
 330 
 331         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &cal, &month, &year) == FAILURE) {
 332                 RETURN_FALSE;
 333         }
 334 
 335         if (cal < 0 || cal >= CAL_NUM_CALS) {
 336                 php_error_docref(NULL, E_WARNING, "invalid calendar ID %pd.", cal);
 337                 RETURN_FALSE;
 338         }
 339 
 340         calendar = &cal_conversion_table[cal];
 341 
 342         sdn_start = calendar->to_jd(year, month, 1);
 343 
 344         if (sdn_start == 0) {
 345                 php_error_docref(NULL, E_WARNING, "invalid date.");
 346                 RETURN_FALSE;
 347         }
 348 
 349         sdn_next = calendar->to_jd(year, 1 + month, 1);
 350 
 351         if (sdn_next == 0) {
 352                 /* If the next month is invalid, then we need to try the first month of
 353                  * the next year, bearing in mind that the next year after 1 BCE is
 354                  * actually 1 AD and not 0. */
 355                 if (year == -1) {
 356                         sdn_next = calendar->to_jd(1, 1, 1);
 357                 }
 358                 else {
 359                         sdn_next = calendar->to_jd(year + 1, 1, 1);
 360                 }
 361         }
 362 
 363         RETURN_LONG(sdn_next - sdn_start);
 364 }
 365 /* }}} */
 366 
 367 /* {{{ proto int cal_to_jd(int calendar, int month, int day, int year)
 368    Converts from a supported calendar to Julian Day Count */
 369 PHP_FUNCTION(cal_to_jd)
 370 {
 371         zend_long cal, month, day, year;
 372 
 373         if (zend_parse_parameters(ZEND_NUM_ARGS(), "llll", &cal, &month, &day, &year) != SUCCESS) {
 374                 RETURN_FALSE;
 375         }
 376 
 377         if (cal < 0 || cal >= CAL_NUM_CALS) {
 378                 php_error_docref(NULL, E_WARNING, "invalid calendar ID %pd.", cal);
 379                 RETURN_FALSE;
 380         }
 381 
 382         RETURN_LONG(cal_conversion_table[cal].to_jd(year, month, day));
 383 }
 384 /* }}} */
 385 
 386 /* {{{ proto array cal_from_jd(int jd, int calendar)
 387    Converts from Julian Day Count to a supported calendar and return extended information */
 388 PHP_FUNCTION(cal_from_jd)
 389 {
 390         zend_long jd, cal;
 391         int month, day, year, dow;
 392         char date[16];
 393         struct cal_entry_t *calendar;
 394 
 395         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &jd, &cal) == FAILURE) {
 396                 RETURN_FALSE;
 397         }
 398 
 399         if (cal < 0 || cal >= CAL_NUM_CALS) {
 400                 php_error_docref(NULL, E_WARNING, "invalid calendar ID %pd", cal);
 401                 RETURN_FALSE;
 402         }
 403         calendar = &cal_conversion_table[cal];
 404 
 405         array_init(return_value);
 406 
 407         calendar->from_jd(jd, &year, &month, &day);
 408 
 409         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 410         add_assoc_string(return_value, "date", date);
 411 
 412         add_assoc_long(return_value, "month", month);
 413         add_assoc_long(return_value, "day", day);
 414         add_assoc_long(return_value, "year", year);
 415 
 416 /* day of week */
 417         dow = DayOfWeek(jd);
 418         add_assoc_long(return_value, "dow", dow);
 419         add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow]);
 420         add_assoc_string(return_value, "dayname", DayNameLong[dow]);
 421 /* month name */
 422         if(cal == CAL_JEWISH) {
 423                 /* special case for Jewish calendar */
 424                 add_assoc_string(return_value, "abbrevmonth", JEWISH_MONTH_NAME(year)[month]);
 425                 add_assoc_string(return_value, "monthname", JEWISH_MONTH_NAME(year)[month]);
 426         } else {
 427                 add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month]);
 428                 add_assoc_string(return_value, "monthname", calendar->month_name_long[month]);
 429         }
 430 }
 431 /* }}} */
 432 
 433 /* {{{ proto string jdtogregorian(int juliandaycount)
 434    Converts a julian day count to a gregorian calendar date */
 435 PHP_FUNCTION(jdtogregorian)
 436 {
 437         zend_long julday;
 438         int year, month, day;
 439         char date[16];
 440 
 441         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &julday) == FAILURE) {
 442                 RETURN_FALSE;
 443         }
 444 
 445         SdnToGregorian(julday, &year, &month, &day);
 446         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 447 
 448         RETURN_STRING(date);
 449 }
 450 /* }}} */
 451 
 452 /* {{{ proto int gregoriantojd(int month, int day, int year)
 453    Converts a gregorian calendar date to julian day count */
 454 PHP_FUNCTION(gregoriantojd)
 455 {
 456         zend_long year, month, day;
 457 
 458         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
 459                 RETURN_FALSE;
 460         }
 461 
 462         RETURN_LONG(GregorianToSdn(year, month, day));
 463 }
 464 /* }}} */
 465 
 466 /* {{{ proto string jdtojulian(int juliandaycount)
 467    Convert a julian day count to a julian calendar date */
 468 PHP_FUNCTION(jdtojulian)
 469 {
 470         zend_long julday;
 471         int year, month, day;
 472         char date[16];
 473 
 474         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &julday) == FAILURE) {
 475                 RETURN_FALSE;
 476         }
 477 
 478         SdnToJulian(julday, &year, &month, &day);
 479         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 480 
 481         RETURN_STRING(date);
 482 }
 483 /* }}} */
 484 
 485 /* {{{ proto int juliantojd(int month, int day, int year)
 486    Converts a julian calendar date to julian day count */
 487 PHP_FUNCTION(juliantojd)
 488 {
 489         zend_long year, month, day;
 490 
 491         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
 492                 RETURN_FALSE;
 493         }
 494 
 495         RETURN_LONG(JulianToSdn(year, month, day));
 496 }
 497 /* }}} */
 498 
 499 /* {{{ heb_number_to_chars*/
 500 /*
 501 caution: the Hebrew format produces non unique result.
 502 for example both: year '5' and year '5000' produce 'ה'.
 503 use the numeric one for calculations. 
 504  */
 505 static char *heb_number_to_chars(int n, int fl, char **ret)
 506 {
 507         char *p, old[18], *endofalafim;
 508 
 509         p = endofalafim = old;
 510 /* 
 511    prevents the option breaking the jewish beliefs, and some other 
 512    critical resources ;)
 513  */
 514         if (n > 9999 || n < 1) {
 515                 *ret = NULL;
 516                 return NULL;
 517         }       
 518 
 519 /* alafim (thousands) case */
 520         if (n / 1000) {
 521                 *p = alef_bet[n / 1000];
 522                 p++;
 523 
 524                 if (CAL_JEWISH_ADD_ALAFIM_GERESH & fl) {
 525                         *p = '\'';
 526                         p++;
 527                 }
 528                 if (CAL_JEWISH_ADD_ALAFIM & fl) {
 529                         strcpy(p, " אלפים ");
 530                         p += 7;
 531                 }
 532 
 533                 endofalafim = p;
 534                 n = n % 1000;
 535         }
 536 
 537 /* tav-tav (tav=400) case */
 538         while (n >= 400) {
 539                 *p = alef_bet[22];
 540                 p++;
 541                 n -= 400;
 542         }
 543 
 544 /* meot (hundreads) case */
 545         if (n >= 100) {
 546                 *p = alef_bet[18 + n / 100];
 547                 p++;
 548                 n = n % 100;
 549         }
 550 
 551 /* tet-vav & tet-zain case (special case for 15 and 16) */
 552         if (n == 15 || n == 16) {
 553                 *p = alef_bet[9];
 554                 p++;
 555                 *p = alef_bet[n - 9];
 556                 p++;
 557         } else {
 558 /* asarot (tens) case */
 559                 if (n >= 10) {
 560                         *p = alef_bet[9 + n / 10];
 561                         p++;
 562                         n = n % 10;
 563                 }
 564 
 565 /* yehidot (ones) case */
 566                 if (n > 0) {
 567                         *p = alef_bet[n];
 568                         p++;
 569                 }
 570         }
 571 
 572         if (CAL_JEWISH_ADD_GERESHAYIM & fl) {
 573                 switch (p - endofalafim) {
 574                 case 0:
 575                         break;
 576                 case 1:
 577                         *p = '\'';
 578                         p++;
 579                         break;
 580                 default:
 581                         *(p) = *(p - 1);
 582                         *(p - 1) = '"';
 583                         p++;
 584                 }
 585         }
 586 
 587         *p = '\0';
 588         *ret = estrndup(old, (p - old) + 1);
 589         p = *ret;
 590         return p;
 591 }
 592 /* }}} */
 593 
 594 /* {{{ proto string jdtojewish(int juliandaycount [, bool hebrew [, int fl]])
 595    Converts a julian day count to a jewish calendar date */
 596 PHP_FUNCTION(jdtojewish)
 597 {
 598         zend_long julday, fl = 0;
 599         zend_bool heb   = 0;
 600         int year, month, day;
 601         char date[16], hebdate[32];
 602         char *dayp, *yearp;
 603 
 604         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|bl", &julday, &heb, &fl) == FAILURE) {
 605                 RETURN_FALSE;
 606         }
 607 
 608         SdnToJewish(julday, &year, &month, &day);
 609         if (!heb) {
 610                 snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 611                 RETURN_STRING(date);
 612         } else {
 613                 if (year <= 0 || year > 9999) {
 614                         php_error_docref(NULL, E_WARNING, "Year out of range (0-9999).");
 615                         RETURN_FALSE;
 616                 }
 617 
 618                 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));
 619 
 620                 if (dayp) {
 621                         efree(dayp);
 622                 }
 623                 if (yearp) {
 624                         efree(yearp);
 625                 }
 626 
 627                 RETURN_STRING(hebdate);
 628 
 629         }
 630 }
 631 /* }}} */
 632 
 633 /* {{{ proto int jewishtojd(int month, int day, int year)
 634    Converts a jewish calendar date to a julian day count */
 635 PHP_FUNCTION(jewishtojd)
 636 {
 637         zend_long year, month, day;
 638 
 639         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
 640                 RETURN_FALSE;
 641         }
 642 
 643         RETURN_LONG(JewishToSdn(year, month, day));
 644 }
 645 /* }}} */
 646 
 647 /* {{{ proto string jdtofrench(int juliandaycount)
 648    Converts a julian day count to a french republic calendar date */
 649 PHP_FUNCTION(jdtofrench)
 650 {
 651         zend_long julday;
 652         int year, month, day;
 653         char date[16];
 654 
 655         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &julday) == FAILURE) {
 656                 RETURN_FALSE;
 657         }
 658 
 659         SdnToFrench(julday, &year, &month, &day);
 660         snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
 661 
 662         RETURN_STRING(date);
 663 }
 664 /* }}} */
 665 
 666 /* {{{ proto int frenchtojd(int month, int day, int year)
 667    Converts a french republic calendar date to julian day count */
 668 PHP_FUNCTION(frenchtojd)
 669 {
 670         zend_long year, month, day;
 671 
 672         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
 673                 RETURN_FALSE;
 674         }
 675 
 676         RETURN_LONG(FrenchToSdn(year, month, day));
 677 }
 678 /* }}} */
 679 
 680 /* {{{ proto mixed jddayofweek(int juliandaycount [, int mode])
 681    Returns name or number of day of week from julian day count */
 682 PHP_FUNCTION(jddayofweek)
 683 {
 684         zend_long julday, mode = CAL_DOW_DAYNO;
 685         int day;
 686         char *daynamel, *daynames;
 687 
 688         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &julday, &mode) == FAILURE) {
 689                 RETURN_FALSE;
 690         }
 691 
 692         day = DayOfWeek(julday);
 693         daynamel = DayNameLong[day];
 694         daynames = DayNameShort[day];
 695 
 696         switch (mode) {
 697         case CAL_DOW_LONG:
 698                 RETURN_STRING(daynamel);
 699                 break;
 700         case CAL_DOW_SHORT:
 701                 RETURN_STRING(daynames);
 702                 break;
 703         case CAL_DOW_DAYNO:
 704         default:
 705                 RETURN_LONG(day);
 706                 break;
 707         }
 708 }
 709 /* }}} */
 710 
 711 /* {{{ proto string jdmonthname(int juliandaycount, int mode)
 712    Returns name of month for julian day count */
 713 PHP_FUNCTION(jdmonthname)
 714 {
 715         zend_long julday, mode;
 716         char *monthname = NULL;
 717         int month, day, year;
 718 
 719         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &julday, &mode) == FAILURE) {
 720                 RETURN_FALSE;
 721         }
 722 
 723         switch (mode) {
 724         case CAL_MONTH_GREGORIAN_LONG:  /* gregorian or julian month */
 725                 SdnToGregorian(julday, &year, &month, &day);
 726                 monthname = MonthNameLong[month];
 727                 break;
 728         case CAL_MONTH_JULIAN_SHORT:    /* gregorian or julian month */
 729                 SdnToJulian(julday, &year, &month, &day);
 730                 monthname = MonthNameShort[month];
 731                 break;
 732         case CAL_MONTH_JULIAN_LONG:     /* gregorian or julian month */
 733                 SdnToJulian(julday, &year, &month, &day);
 734                 monthname = MonthNameLong[month];
 735                 break;
 736         case CAL_MONTH_JEWISH:          /* jewish month */
 737                 SdnToJewish(julday, &year, &month, &day);
 738                 monthname = JEWISH_MONTH_NAME(year)[month];
 739                 break;
 740         case CAL_MONTH_FRENCH:          /* french month */
 741                 SdnToFrench(julday, &year, &month, &day);
 742                 monthname = FrenchMonthName[month];
 743                 break;
 744         default:                                        /* default gregorian */
 745         case CAL_MONTH_GREGORIAN_SHORT: /* gregorian or julian month */
 746                 SdnToGregorian(julday, &year, &month, &day);
 747                 monthname = MonthNameShort[month];
 748                 break;
 749         }
 750 
 751         RETURN_STRING(monthname);
 752 }
 753 /* }}} */
 754 
 755 /*
 756  * Local variables:
 757  * tab-width: 4
 758  * c-basic-offset: 4
 759  * End:
 760  * vim600: sw=4 ts=4 fdm=marker
 761  * vim<600: sw=4 ts=4
 762  */

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