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

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 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:    +----------------------------------------------------------------------+
        !            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>