Annotation of embedaddon/php/ext/calendar/easter.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.2 ! misho       5:    | Copyright (c) 1997-2013 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:    +----------------------------------------------------------------------+
                     19:  */
                     20: /* $Id: */
                     21: 
                     22: #include "php.h"
                     23: #include "php_calendar.h"
                     24: #include "sdncal.h"
                     25: #include <time.h>
                     26: 
                     27: static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, int gm)
                     28: {
                     29: 
                     30:        /* based on code by Simon Kershaw, <webmaster@ely.anglican.org> */
                     31: 
                     32:        struct tm te;
                     33:        long year, golden, solar, lunar, pfm, dom, tmp, easter;
                     34:        long method = CAL_EASTER_DEFAULT;
                     35: 
                     36:        /* Default to the current year if year parameter is not given */
                     37:        {
                     38:                time_t a;
                     39:                struct tm b, *res;
                     40:                time(&a);
                     41:                res = php_localtime_r(&a, &b);
                     42:                if (!res) {
                     43:                        year = 1900;
                     44:                } else {
                     45:                        year = 1900 + b.tm_year;
                     46:                }
                     47:        }
                     48: 
                     49:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                     50:                "|ll", &year, &method) == FAILURE) {
                     51:                        return;
                     52:        }
                     53:  
                     54:        if (gm && (year<1970 || year>2037)) {                           /* out of range for timestamps */
                     55:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "This function is only valid for years between 1970 and 2037 inclusive");
                     56:                RETURN_FALSE;
                     57:        }
                     58: 
                     59:        golden = (year % 19) + 1;                                       /* the Golden number */
                     60: 
                     61:        if ((year <= 1582 && method != CAL_EASTER_ALWAYS_GREGORIAN) ||
                     62:            (year >= 1583 && year <= 1752 && method != CAL_EASTER_ROMAN && method != CAL_EASTER_ALWAYS_GREGORIAN) ||
                     63:             method == CAL_EASTER_ALWAYS_JULIAN) {              /* JULIAN CALENDAR */
                     64:             
                     65:                dom = (year + (year/4) + 5) % 7;                        /* the "Dominical number" - finding a Sunday */
                     66:                if (dom < 0) {
                     67:                        dom += 7;
                     68:                }
                     69: 
                     70:                pfm = (3 - (11*golden) - 7) % 30;                       /* uncorrected date of the Paschal full moon */
                     71:                if (pfm < 0) {
                     72:                        pfm += 30;
                     73:                }
                     74:        } else {                                                        /* GREGORIAN CALENDAR */
                     75:                dom = (year + (year/4) - (year/100) + (year/400)) % 7;  /* the "Domincal number" */
                     76:                if (dom < 0) {
                     77:                        dom += 7;
                     78:                }
                     79: 
                     80:                solar = (year-1600)/100 - (year-1600)/400;              /* the solar and lunar corrections */
                     81:                lunar = (((year-1400) / 100) * 8) / 25;
                     82: 
                     83:                pfm = (3 - (11*golden) + solar - lunar) % 30;           /* uncorrected date of the Paschal full moon */
                     84:                if (pfm < 0) {
                     85:                        pfm += 30;
                     86:                }
                     87:        }
                     88: 
                     89:        if ((pfm == 29) || (pfm == 28 && golden > 11)) {                /* corrected date of the Paschal full moon */
                     90:                pfm--;                                                  /* - days after 21st March                 */
                     91:        }
                     92: 
                     93:        tmp = (4-pfm-dom) % 7;
                     94:        if (tmp < 0) {
                     95:                tmp += 7;
                     96:        }
                     97: 
                     98:        easter = pfm + tmp + 1;                                         /* Easter as the number of days after 21st March */
                     99: 
                    100:        if (gm) {                                                       /* return a timestamp */
                    101:                te.tm_isdst = -1;
                    102:                te.tm_year = year-1900;
                    103:                te.tm_sec = 0;
                    104:                te.tm_min = 0;
                    105:                te.tm_hour = 0;
                    106: 
                    107:                if (easter < 11) {
                    108:                        te.tm_mon = 2;                  /* March */
                    109:                        te.tm_mday = easter+21;
                    110:                } else {
                    111:                        te.tm_mon = 3;                  /* April */
                    112:                        te.tm_mday = easter-10;
                    113:                }
                    114: 
                    115:                Z_LVAL_P(return_value) = mktime(&te);
                    116:        } else {                                                        /* return the days after March 21 */    
                    117:                Z_LVAL_P(return_value) = easter;
                    118:        }
                    119: 
                    120:         Z_TYPE_P(return_value) = IS_LONG;
                    121: 
                    122: }
                    123: 
                    124: /* {{{ proto int easter_date([int year])
                    125:    Return the timestamp of midnight on Easter of a given year (defaults to current year) */
                    126: PHP_FUNCTION(easter_date)
                    127: {
                    128:        _cal_easter(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                    129: }
                    130: /* }}} */
                    131: 
                    132: /* {{{ proto int easter_days([int year, [int method]])
                    133:    Return the number of days after March 21 that Easter falls on for a given year (defaults to current year) */
                    134: PHP_FUNCTION(easter_days)
                    135: {
                    136:        _cal_easter(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                    137: }
                    138: /* }}} */
                    139: 
                    140: /*
                    141:  * Local variables:
                    142:  * tab-width: 4
                    143:  * c-basic-offset: 4
                    144:  * End:
                    145:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>