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