calendar.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Shane Caraveo <shane@caraveo.com> |
  14. | Colin Viebrock <colin@easydns.com> |
  15. | Hartmut Holzgraefe <hholzgra@php.net> |
  16. | Wez Furlong <wez@thebrainroom.com> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "php.h"
  23. #include "ext/standard/info.h"
  24. #include "calendar_arginfo.h"
  25. #include "php_calendar.h"
  26. #include "sdncal.h"
  27. #include <stdio.h>
  28. #ifdef PHP_WIN32
  29. /* This conflicts with a define in winnls.h, but that header is needed
  30. to have GetACP(). */
  31. #undef CAL_GREGORIAN
  32. #endif
  33. zend_module_entry calendar_module_entry = {
  34. STANDARD_MODULE_HEADER,
  35. "calendar",
  36. ext_functions,
  37. PHP_MINIT(calendar),
  38. NULL,
  39. NULL,
  40. NULL,
  41. PHP_MINFO(calendar),
  42. PHP_CALENDAR_VERSION,
  43. STANDARD_MODULE_PROPERTIES,
  44. };
  45. #ifdef COMPILE_DL_CALENDAR
  46. ZEND_GET_MODULE(calendar)
  47. #endif
  48. /* this order must match the conversion table below */
  49. enum cal_name_type_t {
  50. CAL_GREGORIAN = 0,
  51. CAL_JULIAN,
  52. CAL_JEWISH,
  53. CAL_FRENCH,
  54. CAL_NUM_CALS
  55. };
  56. typedef zend_long (*cal_to_jd_func_t) (int month, int day, int year);
  57. typedef void (*cal_from_jd_func_t) (zend_long jd, int *year, int *month, int *day);
  58. typedef char *(*cal_as_string_func_t) (int year, int month, int day);
  59. struct cal_entry_t {
  60. const char *name;
  61. const char *symbol;
  62. cal_to_jd_func_t to_jd;
  63. cal_from_jd_func_t from_jd;
  64. int num_months;
  65. int max_days_in_month;
  66. const char * const * month_name_short;
  67. const char * const * month_name_long;
  68. };
  69. static const struct cal_entry_t cal_conversion_table[CAL_NUM_CALS] = {
  70. {"Gregorian", "CAL_GREGORIAN", GregorianToSdn, SdnToGregorian, 12, 31,
  71. MonthNameShort, MonthNameLong},
  72. {"Julian", "CAL_JULIAN", JulianToSdn, SdnToJulian, 12, 31,
  73. MonthNameShort, MonthNameLong},
  74. {"Jewish", "CAL_JEWISH", JewishToSdn, SdnToJewish, 13, 30,
  75. JewishMonthNameLeap, JewishMonthNameLeap},
  76. {"French", "CAL_FRENCH", FrenchToSdn, SdnToFrench, 13, 30,
  77. FrenchMonthName, FrenchMonthName}
  78. };
  79. #define JEWISH_MONTH_NAME(year) ((monthsPerYear[((year)-1) % 19] == 13)?JewishMonthNameLeap:JewishMonthName)
  80. #define JEWISH_HEB_MONTH_NAME(year) ((monthsPerYear[((year)-1) % 19] == 13)?JewishMonthHebNameLeap:JewishMonthHebName)
  81. /* For jddayofweek */
  82. enum { CAL_DOW_DAYNO, CAL_DOW_LONG, CAL_DOW_SHORT };
  83. /* For jdmonthname */
  84. enum { CAL_MONTH_GREGORIAN_SHORT, CAL_MONTH_GREGORIAN_LONG,
  85. CAL_MONTH_JULIAN_SHORT, CAL_MONTH_JULIAN_LONG, CAL_MONTH_JEWISH,
  86. CAL_MONTH_FRENCH
  87. };
  88. /* For heb_number_to_chars escape sequences of אבגדהוזחטיכלמנסעפצקרשת
  89. ISO-8859-8 Hebrew alphabet */
  90. static const char alef_bet[25] = "0\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEB\xEC\xEE\xF0\xF1\xF2\xF4\xF6\xF7\xF8\xF9\xFA";
  91. #define CAL_JEWISH_ADD_ALAFIM_GERESH 0x2
  92. #define CAL_JEWISH_ADD_ALAFIM 0x4
  93. #define CAL_JEWISH_ADD_GERESHAYIM 0x8
  94. PHP_MINIT_FUNCTION(calendar)
  95. {
  96. REGISTER_LONG_CONSTANT("CAL_GREGORIAN", CAL_GREGORIAN, CONST_CS | CONST_PERSISTENT);
  97. REGISTER_LONG_CONSTANT("CAL_JULIAN", CAL_JULIAN, CONST_CS | CONST_PERSISTENT);
  98. REGISTER_LONG_CONSTANT("CAL_JEWISH", CAL_JEWISH, CONST_CS | CONST_PERSISTENT);
  99. REGISTER_LONG_CONSTANT("CAL_FRENCH", CAL_FRENCH, CONST_CS | CONST_PERSISTENT);
  100. REGISTER_LONG_CONSTANT("CAL_NUM_CALS", CAL_NUM_CALS, CONST_CS | CONST_PERSISTENT);
  101. /* constants for jddayofweek */
  102. REGISTER_LONG_CONSTANT("CAL_DOW_DAYNO", CAL_DOW_DAYNO, CONST_CS | CONST_PERSISTENT);
  103. REGISTER_LONG_CONSTANT("CAL_DOW_SHORT", CAL_DOW_SHORT, CONST_CS | CONST_PERSISTENT);
  104. REGISTER_LONG_CONSTANT("CAL_DOW_LONG", CAL_DOW_LONG, CONST_CS | CONST_PERSISTENT);
  105. /* constants for jdmonthname */
  106. REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_SHORT", CAL_MONTH_GREGORIAN_SHORT, CONST_CS | CONST_PERSISTENT);
  107. REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_LONG", CAL_MONTH_GREGORIAN_LONG, CONST_CS | CONST_PERSISTENT);
  108. REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_SHORT", CAL_MONTH_JULIAN_SHORT, CONST_CS | CONST_PERSISTENT);
  109. REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_LONG", CAL_MONTH_JULIAN_LONG, CONST_CS | CONST_PERSISTENT);
  110. REGISTER_LONG_CONSTANT("CAL_MONTH_JEWISH", CAL_MONTH_JEWISH, CONST_CS | CONST_PERSISTENT);
  111. REGISTER_LONG_CONSTANT("CAL_MONTH_FRENCH", CAL_MONTH_FRENCH, CONST_CS | CONST_PERSISTENT);
  112. /* constants for easter calculation */
  113. REGISTER_LONG_CONSTANT("CAL_EASTER_DEFAULT", CAL_EASTER_DEFAULT, CONST_CS | CONST_PERSISTENT);
  114. REGISTER_LONG_CONSTANT("CAL_EASTER_ROMAN", CAL_EASTER_ROMAN, CONST_CS | CONST_PERSISTENT);
  115. REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_GREGORIAN", CAL_EASTER_ALWAYS_GREGORIAN, CONST_CS | CONST_PERSISTENT);
  116. REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_JULIAN", CAL_EASTER_ALWAYS_JULIAN, CONST_CS | CONST_PERSISTENT);
  117. /* constants for Jewish date formatting */
  118. REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_ALAFIM_GERESH", CAL_JEWISH_ADD_ALAFIM_GERESH, CONST_CS | CONST_PERSISTENT);
  119. REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_ALAFIM", CAL_JEWISH_ADD_ALAFIM, CONST_CS | CONST_PERSISTENT);
  120. REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_GERESHAYIM", CAL_JEWISH_ADD_GERESHAYIM, CONST_CS | CONST_PERSISTENT);
  121. return SUCCESS;
  122. }
  123. PHP_MINFO_FUNCTION(calendar)
  124. {
  125. php_info_print_table_start();
  126. php_info_print_table_row(2, "Calendar support", "enabled");
  127. php_info_print_table_end();
  128. }
  129. static void _php_cal_info(int cal, zval *ret)
  130. {
  131. zval months, smonths;
  132. int i;
  133. const struct cal_entry_t *calendar;
  134. calendar = &cal_conversion_table[cal];
  135. array_init(ret);
  136. array_init(&months);
  137. array_init(&smonths);
  138. for (i = 1; i <= calendar->num_months; i++) {
  139. add_index_string(&months, i, calendar->month_name_long[i]);
  140. add_index_string(&smonths, i, calendar->month_name_short[i]);
  141. }
  142. add_assoc_zval(ret, "months", &months);
  143. add_assoc_zval(ret, "abbrevmonths", &smonths);
  144. add_assoc_long(ret, "maxdaysinmonth", calendar->max_days_in_month);
  145. add_assoc_string(ret, "calname", calendar->name);
  146. add_assoc_string(ret, "calsymbol", calendar->symbol);
  147. }
  148. /* {{{ Returns information about a particular calendar */
  149. PHP_FUNCTION(cal_info)
  150. {
  151. zend_long cal = -1;
  152. if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &cal) == FAILURE) {
  153. RETURN_THROWS();
  154. }
  155. if (cal == -1) {
  156. int i;
  157. zval val;
  158. array_init(return_value);
  159. for (i = 0; i < CAL_NUM_CALS; i++) {
  160. _php_cal_info(i, &val);
  161. add_index_zval(return_value, i, &val);
  162. }
  163. return;
  164. }
  165. if (cal < 0 || cal >= CAL_NUM_CALS) {
  166. zend_argument_value_error(1, "must be a valid calendar ID");
  167. RETURN_THROWS();
  168. }
  169. _php_cal_info(cal, return_value);
  170. }
  171. /* }}} */
  172. /* {{{ Returns the number of days in a month for a given year and calendar */
  173. PHP_FUNCTION(cal_days_in_month)
  174. {
  175. zend_long cal, month, year;
  176. const struct cal_entry_t *calendar;
  177. zend_long sdn_start, sdn_next;
  178. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &cal, &month, &year) == FAILURE) {
  179. RETURN_THROWS();
  180. }
  181. if (cal < 0 || cal >= CAL_NUM_CALS) {
  182. zend_argument_value_error(1, "must be a valid calendar ID");
  183. RETURN_THROWS();
  184. }
  185. calendar = &cal_conversion_table[cal];
  186. sdn_start = calendar->to_jd(year, month, 1);
  187. if (sdn_start == 0) {
  188. zend_value_error("Invalid date");
  189. RETURN_THROWS();
  190. }
  191. sdn_next = calendar->to_jd(year, 1 + month, 1);
  192. if (sdn_next == 0) {
  193. /* If the next month is invalid, then we need to try the first month of
  194. * the next year, bearing in mind that the next year after 1 BCE is
  195. * actually 1 AD and not 0. */
  196. if (year == -1) {
  197. sdn_next = calendar->to_jd(1, 1, 1);
  198. }
  199. else {
  200. sdn_next = calendar->to_jd(year + 1, 1, 1);
  201. if (cal == CAL_FRENCH && sdn_next == 0) {
  202. /* The French calendar ends on 0014-13-05. */
  203. sdn_next = 2380953;
  204. }
  205. }
  206. }
  207. RETURN_LONG(sdn_next - sdn_start);
  208. }
  209. /* }}} */
  210. /* {{{ Converts from a supported calendar to Julian Day Count */
  211. PHP_FUNCTION(cal_to_jd)
  212. {
  213. zend_long cal, month, day, year;
  214. if (zend_parse_parameters(ZEND_NUM_ARGS(), "llll", &cal, &month, &day, &year) != SUCCESS) {
  215. RETURN_THROWS();
  216. }
  217. if (cal < 0 || cal >= CAL_NUM_CALS) {
  218. zend_argument_value_error(1, "must be a valid calendar ID");
  219. RETURN_THROWS();
  220. }
  221. RETURN_LONG(cal_conversion_table[cal].to_jd(year, month, day));
  222. }
  223. /* }}} */
  224. /* {{{ Converts from Julian Day Count to a supported calendar and return extended information */
  225. PHP_FUNCTION(cal_from_jd)
  226. {
  227. zend_long jd, cal;
  228. int month, day, year, dow;
  229. const struct cal_entry_t *calendar;
  230. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &jd, &cal) == FAILURE) {
  231. RETURN_THROWS();
  232. }
  233. if (cal < 0 || cal >= CAL_NUM_CALS) {
  234. zend_argument_value_error(2, "must be a valid calendar ID");
  235. RETURN_THROWS();
  236. }
  237. calendar = &cal_conversion_table[cal];
  238. array_init(return_value);
  239. calendar->from_jd(jd, &year, &month, &day);
  240. add_assoc_str(return_value, "date",
  241. zend_strpprintf(0, "%i/%i/%i", month, day, year));
  242. add_assoc_long(return_value, "month", month);
  243. add_assoc_long(return_value, "day", day);
  244. add_assoc_long(return_value, "year", year);
  245. /* day of week */
  246. if (cal != CAL_JEWISH || year > 0) {
  247. dow = DayOfWeek(jd);
  248. add_assoc_long(return_value, "dow", dow);
  249. add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow]);
  250. add_assoc_string(return_value, "dayname", DayNameLong[dow]);
  251. } else {
  252. add_assoc_null(return_value, "dow");
  253. add_assoc_string(return_value, "abbrevdayname", "");
  254. add_assoc_string(return_value, "dayname", "");
  255. }
  256. /* month name */
  257. if(cal == CAL_JEWISH) {
  258. /* special case for Jewish calendar */
  259. add_assoc_string(return_value, "abbrevmonth", (year > 0 ? JEWISH_MONTH_NAME(year)[month] : ""));
  260. add_assoc_string(return_value, "monthname", (year > 0 ? JEWISH_MONTH_NAME(year)[month] : ""));
  261. } else {
  262. add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month]);
  263. add_assoc_string(return_value, "monthname", calendar->month_name_long[month]);
  264. }
  265. }
  266. /* }}} */
  267. /* {{{ Converts a julian day count to a gregorian calendar date */
  268. PHP_FUNCTION(jdtogregorian)
  269. {
  270. zend_long julday;
  271. int year, month, day;
  272. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &julday) == FAILURE) {
  273. RETURN_THROWS();
  274. }
  275. SdnToGregorian(julday, &year, &month, &day);
  276. RETURN_NEW_STR(zend_strpprintf(0, "%i/%i/%i", month, day, year));
  277. }
  278. /* }}} */
  279. /* {{{ Converts a gregorian calendar date to julian day count */
  280. PHP_FUNCTION(gregoriantojd)
  281. {
  282. zend_long year, month, day;
  283. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
  284. RETURN_THROWS();
  285. }
  286. RETURN_LONG(GregorianToSdn(year, month, day));
  287. }
  288. /* }}} */
  289. /* {{{ Convert a julian day count to a julian calendar date */
  290. PHP_FUNCTION(jdtojulian)
  291. {
  292. zend_long julday;
  293. int year, month, day;
  294. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &julday) == FAILURE) {
  295. RETURN_THROWS();
  296. }
  297. SdnToJulian(julday, &year, &month, &day);
  298. RETURN_NEW_STR(zend_strpprintf(0, "%i/%i/%i", month, day, year));
  299. }
  300. /* }}} */
  301. /* {{{ Converts a julian calendar date to julian day count */
  302. PHP_FUNCTION(juliantojd)
  303. {
  304. zend_long year, month, day;
  305. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
  306. RETURN_THROWS();
  307. }
  308. RETURN_LONG(JulianToSdn(year, month, day));
  309. }
  310. /* }}} */
  311. /* {{{ heb_number_to_chars*/
  312. /*
  313. caution: the Hebrew format produces non unique result.
  314. for example both: year '5' and year '5000' produce 'ה'.
  315. use the numeric one for calculations.
  316. */
  317. static char *heb_number_to_chars(int n, int fl, char **ret)
  318. {
  319. char *p, old[18], *endofalafim;
  320. p = endofalafim = old;
  321. /*
  322. prevents the option breaking the jewish beliefs, and some other
  323. critical resources ;)
  324. */
  325. if (n > 9999 || n < 1) {
  326. *ret = NULL;
  327. return NULL;
  328. }
  329. /* alafim (thousands) case */
  330. if (n / 1000) {
  331. *p = alef_bet[n / 1000];
  332. p++;
  333. if (CAL_JEWISH_ADD_ALAFIM_GERESH & fl) {
  334. *p = '\'';
  335. p++;
  336. }
  337. if (CAL_JEWISH_ADD_ALAFIM & fl) {
  338. /* Escape sequences of Hebrew characters in ISO-8859-8: אלפים */
  339. strcpy(p, " \xE0\xEC\xF4\xE9\xED ");
  340. p += 7;
  341. }
  342. endofalafim = p;
  343. n = n % 1000;
  344. }
  345. /* tav-tav (tav=400) case */
  346. while (n >= 400) {
  347. *p = alef_bet[22];
  348. p++;
  349. n -= 400;
  350. }
  351. /* meot (hundreads) case */
  352. if (n >= 100) {
  353. *p = alef_bet[18 + n / 100];
  354. p++;
  355. n = n % 100;
  356. }
  357. /* tet-vav & tet-zain case (special case for 15 and 16) */
  358. if (n == 15 || n == 16) {
  359. *p = alef_bet[9];
  360. p++;
  361. *p = alef_bet[n - 9];
  362. p++;
  363. } else {
  364. /* asarot (tens) case */
  365. if (n >= 10) {
  366. *p = alef_bet[9 + n / 10];
  367. p++;
  368. n = n % 10;
  369. }
  370. /* yehidot (ones) case */
  371. if (n > 0) {
  372. *p = alef_bet[n];
  373. p++;
  374. }
  375. }
  376. if (CAL_JEWISH_ADD_GERESHAYIM & fl) {
  377. switch (p - endofalafim) {
  378. case 0:
  379. break;
  380. case 1:
  381. *p = '\'';
  382. p++;
  383. break;
  384. default:
  385. *(p) = *(p - 1);
  386. *(p - 1) = '"';
  387. p++;
  388. }
  389. }
  390. *p = '\0';
  391. *ret = estrndup(old, (p - old) + 1);
  392. p = *ret;
  393. return p;
  394. }
  395. /* }}} */
  396. /* {{{ Converts a julian day count to a jewish calendar date */
  397. PHP_FUNCTION(jdtojewish)
  398. {
  399. zend_long julday, fl = 0;
  400. bool heb = 0;
  401. int year, month, day;
  402. char *dayp, *yearp;
  403. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|bl", &julday, &heb, &fl) == FAILURE) {
  404. RETURN_THROWS();
  405. }
  406. SdnToJewish(julday, &year, &month, &day);
  407. if (!heb) {
  408. RETURN_NEW_STR(zend_strpprintf(0, "%i/%i/%i", month, day, year));
  409. } else {
  410. if (year <= 0 || year > 9999) {
  411. zend_value_error("Year out of range (0-9999)");
  412. RETURN_THROWS();
  413. }
  414. RETVAL_NEW_STR(zend_strpprintf(0, "%s %s %s", heb_number_to_chars(day, fl, &dayp), JEWISH_HEB_MONTH_NAME(year)[month], heb_number_to_chars(year, fl, &yearp)));
  415. if (dayp) {
  416. efree(dayp);
  417. }
  418. if (yearp) {
  419. efree(yearp);
  420. }
  421. }
  422. }
  423. /* }}} */
  424. /* {{{ Converts a jewish calendar date to a julian day count */
  425. PHP_FUNCTION(jewishtojd)
  426. {
  427. zend_long year, month, day;
  428. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
  429. RETURN_THROWS();
  430. }
  431. RETURN_LONG(JewishToSdn(year, month, day));
  432. }
  433. /* }}} */
  434. /* {{{ Converts a julian day count to a french republic calendar date */
  435. PHP_FUNCTION(jdtofrench)
  436. {
  437. zend_long julday;
  438. int year, month, day;
  439. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &julday) == FAILURE) {
  440. RETURN_THROWS();
  441. }
  442. SdnToFrench(julday, &year, &month, &day);
  443. RETURN_NEW_STR(zend_strpprintf(0, "%i/%i/%i", month, day, year));
  444. }
  445. /* }}} */
  446. /* {{{ Converts a french republic calendar date to julian day count */
  447. PHP_FUNCTION(frenchtojd)
  448. {
  449. zend_long year, month, day;
  450. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) {
  451. RETURN_THROWS();
  452. }
  453. RETURN_LONG(FrenchToSdn(year, month, day));
  454. }
  455. /* }}} */
  456. /* {{{ Returns name or number of day of week from julian day count */
  457. PHP_FUNCTION(jddayofweek)
  458. {
  459. zend_long julday, mode = CAL_DOW_DAYNO;
  460. int day;
  461. const char *daynamel, *daynames;
  462. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &julday, &mode) == FAILURE) {
  463. RETURN_THROWS();
  464. }
  465. day = DayOfWeek(julday);
  466. daynamel = DayNameLong[day];
  467. daynames = DayNameShort[day];
  468. switch (mode) {
  469. case CAL_DOW_LONG:
  470. RETURN_STRING(daynamel);
  471. break;
  472. case CAL_DOW_SHORT:
  473. RETURN_STRING(daynames);
  474. break;
  475. case CAL_DOW_DAYNO:
  476. default:
  477. RETURN_LONG(day);
  478. break;
  479. }
  480. }
  481. /* }}} */
  482. /* {{{ Returns name of month for julian day count */
  483. PHP_FUNCTION(jdmonthname)
  484. {
  485. zend_long julday, mode;
  486. const char *monthname = NULL;
  487. int month, day, year;
  488. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &julday, &mode) == FAILURE) {
  489. RETURN_THROWS();
  490. }
  491. switch (mode) {
  492. case CAL_MONTH_GREGORIAN_LONG: /* gregorian or julian month */
  493. SdnToGregorian(julday, &year, &month, &day);
  494. monthname = MonthNameLong[month];
  495. break;
  496. case CAL_MONTH_JULIAN_SHORT: /* gregorian or julian month */
  497. SdnToJulian(julday, &year, &month, &day);
  498. monthname = MonthNameShort[month];
  499. break;
  500. case CAL_MONTH_JULIAN_LONG: /* gregorian or julian month */
  501. SdnToJulian(julday, &year, &month, &day);
  502. monthname = MonthNameLong[month];
  503. break;
  504. case CAL_MONTH_JEWISH: /* jewish month */
  505. SdnToJewish(julday, &year, &month, &day);
  506. monthname = (year > 0 ? JEWISH_MONTH_NAME(year)[month] : "");
  507. break;
  508. case CAL_MONTH_FRENCH: /* french month */
  509. SdnToFrench(julday, &year, &month, &day);
  510. monthname = FrenchMonthName[month];
  511. break;
  512. default: /* default gregorian */
  513. case CAL_MONTH_GREGORIAN_SHORT: /* gregorian or julian month */
  514. SdnToGregorian(julday, &year, &month, &day);
  515. monthname = MonthNameShort[month];
  516. break;
  517. }
  518. RETURN_STRING(monthname);
  519. }
  520. /* }}} */