File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / calendar / easter.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:41 2014 UTC (10 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

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