mirror of
https://github.com/php/php-src.git
synced 2024-11-26 03:16:33 +08:00
@ new idate() function.
@ new date_sunrise() function. @ new date_sunset() function. #since i have no premission updating the win32 project file, i'm sending patch on the list.
This commit is contained in:
parent
2cc68ad7ad
commit
ea8d11cc87
@ -285,6 +285,7 @@ function_entry basic_functions[] = {
|
||||
|
||||
PHP_FE(strtotime, NULL)
|
||||
PHP_FE(date, NULL)
|
||||
PHP_FE(idate, NULL)
|
||||
PHP_FE(gmdate, NULL)
|
||||
PHP_FE(getdate, NULL)
|
||||
PHP_FE(localtime, NULL)
|
||||
@ -899,6 +900,8 @@ function_entry basic_functions[] = {
|
||||
|
||||
PHP_FE(output_add_rewrite_var, NULL)
|
||||
PHP_FE(output_reset_rewrite_vars, NULL)
|
||||
PHP_FE(date_sunrise, NULL)
|
||||
PHP_FE(date_sunset, NULL)
|
||||
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
@ -936,6 +939,10 @@ static PHP_INI_MH(OnUpdateSafeModeAllowedEnvVars)
|
||||
PHP_INI_BEGIN()
|
||||
PHP_INI_ENTRY_EX("safe_mode_protected_env_vars", SAFE_MODE_PROTECTED_ENV_VARS, PHP_INI_SYSTEM, OnUpdateSafeModeProtectedEnvVars, NULL)
|
||||
PHP_INI_ENTRY_EX("safe_mode_allowed_env_vars", SAFE_MODE_ALLOWED_ENV_VARS, PHP_INI_SYSTEM, OnUpdateSafeModeAllowedEnvVars, NULL)
|
||||
PHP_INI_ENTRY("date.default_latitude", DATE_DEFAULT_LATITUDE, PHP_INI_ALL, NULL)
|
||||
PHP_INI_ENTRY("date.default_longitude", DATE_DEFAULT_LONGITUDE, PHP_INI_ALL, NULL)
|
||||
PHP_INI_ENTRY("date.sunset_zenith",DATE_SUNSET_ZENITH, PHP_INI_ALL, NULL)
|
||||
PHP_INI_ENTRY("date.sunrise_zenith",DATE_SUNRISE_ZENITH, PHP_INI_ALL, NULL)
|
||||
PHP_INI_END()
|
||||
|
||||
|
||||
@ -1020,6 +1027,10 @@ PHP_MINIT_FUNCTION(basic)
|
||||
REGISTER_LONG_CONSTANT("INI_PERDIR", ZEND_INI_PERDIR, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("INI_SYSTEM", ZEND_INI_SYSTEM, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("INI_ALL", ZEND_INI_ALL, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("SUNFUNCS_RET_TIMESTAMP", SUNFUNCS_RET_TIMESTAMP, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("SUNFUNCS_RET_STRING", SUNFUNCS_RET_STRING, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("SUNFUNCS_RET_DOUBLE", SUNFUNCS_RET_DOUBLE, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
#define REGISTER_MATH_CONSTANT(x) REGISTER_DOUBLE_CONSTANT(#x, x, CONST_CS | CONST_PERSISTENT)
|
||||
REGISTER_MATH_CONSTANT(M_E);
|
||||
|
@ -284,6 +284,6 @@ PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32.
|
||||
incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
|
||||
http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
|
||||
var_unserializer.c ftok.c aggregation.c sha1.c user_filters.c \
|
||||
filters.c proc_open.c )
|
||||
filters.c proc_open.c sunfuncs.c)
|
||||
|
||||
PHP_ADD_MAKEFILE_FRAGMENT
|
||||
|
@ -630,6 +630,146 @@ PHP_FUNCTION(date)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ idate */
|
||||
int idate(char format, int timestamp, int gm)
|
||||
{
|
||||
time_t the_time;
|
||||
struct tm *ta, tmbuf;
|
||||
int h, beat, fd, wd, yd, wk;
|
||||
#if !HAVE_TM_GMTOFF
|
||||
long tzone;
|
||||
char *tname[2]= {"GMT Standard Time", "BST"};
|
||||
#endif
|
||||
|
||||
the_time = timestamp;
|
||||
|
||||
if (gm) {
|
||||
ta = php_gmtime_r(&the_time, &tmbuf);
|
||||
#if !HAVE_TM_GMTOFF
|
||||
tzone = 0;
|
||||
#endif
|
||||
} else {
|
||||
ta = php_localtime_r(&the_time, &tmbuf);
|
||||
#if !HAVE_TM_GMTOFF
|
||||
#ifdef __CYGWIN__
|
||||
tzone = _timezone;
|
||||
#else
|
||||
tzone = timezone;
|
||||
#endif
|
||||
tname[0] = tzname[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case 'U': /* seconds since the epoch */
|
||||
return (long)the_time;
|
||||
case 'Y': /* year, numeric, 4 digits */
|
||||
return ta->tm_year + YEAR_BASE;
|
||||
case 'z': /* day (of the year) */
|
||||
return ta->tm_yday;
|
||||
case 'y': /* year, numeric, 2 digits */
|
||||
return (ta->tm_year)%100;
|
||||
case 'm': /* month, numeric */
|
||||
case 'n':
|
||||
return ta->tm_mon + 1;
|
||||
case 'd': /* day of the month, numeric */
|
||||
case 'j':
|
||||
return ta->tm_mday;
|
||||
case 'H': /* hour, numeric, 24 hour format */
|
||||
case 'G':
|
||||
return ta->tm_hour;
|
||||
case 'h': /* hour, numeric, 12 hour format */
|
||||
case 'g':
|
||||
h = ta->tm_hour % 12; if (h==0) h = 12;
|
||||
return h;
|
||||
case 'i': /* minutes, numeric */
|
||||
return ta->tm_min;
|
||||
case 's': /* seconds, numeric */
|
||||
return ta->tm_sec;
|
||||
case 't': /* days in current month */
|
||||
return phpday_tab[isleap((ta->tm_year+YEAR_BASE))][ta->tm_mon];
|
||||
case 'w': /* day of the week, numeric EXTENSION */
|
||||
return ta->tm_wday;
|
||||
case 'Z': /* timezone offset in seconds */
|
||||
#if HAVE_TM_GMTOFF
|
||||
return ta->tm_gmtoff;
|
||||
#else
|
||||
return ta->tm_isdst ? -(tzone- 3600) : -tzone;
|
||||
#endif
|
||||
case 'L': /* boolean for leapyear */
|
||||
return isleap(ta->tm_year+YEAR_BASE)?1:0;
|
||||
case 'B': /* Swatch Beat a.k.a. Internet Time */
|
||||
beat = (((((long)the_time)-(((long)the_time) -
|
||||
((((long)the_time) % 86400) + 3600))) * 10) / 864);
|
||||
while (beat < 0) {
|
||||
beat += 1000;
|
||||
}
|
||||
beat = beat % 1000;
|
||||
return beat;
|
||||
case 'I':
|
||||
return ta->tm_isdst;
|
||||
case 'W': /* ISO-8601 week number of year, weeks starting on Monday */
|
||||
wd = ta->tm_wday==0 ? 6 : ta->tm_wday-1;/* weekday */
|
||||
yd = ta->tm_yday + 1; /* days since January 1st */
|
||||
fd = (7 + wd - yd % 7+ 1) % 7; /* weekday (1st January) */ /* week is a last year week (52 or 53) */
|
||||
if ((yd <= 7 - fd) && fd > 3){
|
||||
wk = (fd == 4 || (fd == 5 && isleap((ta->tm_year + YEAR_BASE - 1)))) ? 53 : 52;
|
||||
}
|
||||
/* week is a next year week (1) */
|
||||
else if (isleap((ta->tm_year+YEAR_BASE)) + 365 - yd < 3 - wd){
|
||||
wk = 1;
|
||||
}
|
||||
/* normal week */
|
||||
else {
|
||||
wk = (yd + 6 - wd + fd) / 7 - (fd > 3);
|
||||
}
|
||||
return wk;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int idate(string format [, int timestamp])
|
||||
Format a local time/date as integer */
|
||||
PHP_FUNCTION(idate)
|
||||
{
|
||||
pval **format, **timestamp;
|
||||
int t, ret;
|
||||
|
||||
switch(ZEND_NUM_ARGS()) {
|
||||
case 1:
|
||||
if (zend_get_parameters_ex(1, &format) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
t = time(NULL);
|
||||
break;
|
||||
case 2:
|
||||
if (zend_get_parameters_ex(2, &format, ×tamp) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long_ex(timestamp);
|
||||
t = Z_LVAL_PP(timestamp);
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_string_ex(format);
|
||||
|
||||
if (Z_STRLEN_PP(format) != 1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "idate format is one char");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ret = idate(Z_STRVAL_PP(format)[0], t, 0);
|
||||
RETURN_LONG(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto string gmdate(string format [, int timestamp])
|
||||
Format a GMT/UTC date/time */
|
||||
PHP_FUNCTION(gmdate)
|
||||
|
@ -26,6 +26,7 @@ PHP_FUNCTION(time);
|
||||
PHP_FUNCTION(mktime);
|
||||
PHP_FUNCTION(gmmktime);
|
||||
PHP_FUNCTION(date);
|
||||
PHP_FUNCTION(idate);
|
||||
PHP_FUNCTION(gmdate);
|
||||
PHP_FUNCTION(localtime);
|
||||
PHP_FUNCTION(getdate);
|
||||
@ -36,6 +37,7 @@ PHP_FUNCTION(gmstrftime);
|
||||
#endif
|
||||
PHP_FUNCTION(strtotime);
|
||||
|
||||
int idate(char format, int timestamp, int gm);
|
||||
extern char *php_std_date(time_t t);
|
||||
void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm);
|
||||
#if HAVE_STRFTIME
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "php_ftok.h"
|
||||
#include "php_type.h"
|
||||
#include "aggregation.h"
|
||||
#include "sunfuncs.h"
|
||||
|
||||
#define phpext_standard_ptr basic_functions_module_ptr
|
||||
PHP_MINIT_FUNCTION(standard_filters);
|
||||
|
332
ext/standard/sunfuncs.c
Normal file
332
ext/standard/sunfuncs.c
Normal file
@ -0,0 +1,332 @@
|
||||
/*
|
||||
The sun position algorithm taken from the 'US Naval Observatory's
|
||||
Almanac for Computers', implemented by Ken Bloom <kekabloom@ucdavis.edu>
|
||||
for the zmanim project <http://sourceforge.net/projects/zmanim/>
|
||||
and finally converted to C by Moshe Doron <mosdoron@netvision.net.il>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "sunfuncs.h"
|
||||
#include "php.h"
|
||||
#include "datetime.h"
|
||||
#include "php_ini.h"
|
||||
|
||||
|
||||
|
||||
/* {{{ proto mixed sunrise(mixed time[, int format][, float latitude][, float longitude][, float zenith,][ float gmt_offset])
|
||||
Returns time of sunrise for a given day & location */
|
||||
PHP_FUNCTION(date_sunrise)
|
||||
{
|
||||
zval *date;
|
||||
double latitude, longitude, zenith, gmt_offset, ret;
|
||||
int time, N, retformat;
|
||||
char retstr[6];
|
||||
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ldddd", &date, &retformat, &latitude, &longitude, &zenith, &gmt_offset) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
switch(Z_TYPE_P(date)){
|
||||
case IS_LONG:
|
||||
time = Z_LVAL_P(date);
|
||||
break;
|
||||
case IS_STRING:
|
||||
/* todo: more user friendly format */
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "date must be timestamp for now");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
N = idate('z',time,0)+1;
|
||||
|
||||
switch(ZEND_NUM_ARGS()){
|
||||
case 1:
|
||||
retformat = SUNFUNCS_RET_STRING;
|
||||
case 2:
|
||||
latitude = INI_FLT("date.default_latitude");
|
||||
case 3:
|
||||
longitude = INI_FLT("date.default_longitude");
|
||||
case 4:
|
||||
zenith = INI_FLT("date.sunrise_zenith");
|
||||
case 5:
|
||||
gmt_offset = idate('Z',time,0)/3600;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = sunrise(N, latitude, longitude, zenith) + gmt_offset;
|
||||
|
||||
switch(retformat){
|
||||
case SUNFUNCS_RET_TIMESTAMP:
|
||||
RETURN_LONG((int)(time-(time%(24*3600)))+(int)(60*ret));
|
||||
break;
|
||||
case SUNFUNCS_RET_STRING:
|
||||
N = (int)ret;
|
||||
sprintf(retstr, "%02d:%02d", N,(int)(60*(ret-(double)N)));
|
||||
RETVAL_STRINGL(retstr, 5, 1);
|
||||
break;
|
||||
case SUNFUNCS_RET_DOUBLE:
|
||||
RETURN_DOUBLE(ret);
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid format");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* returns time in UTC */
|
||||
double sunrise(long N, double latitude, double longitude, double zenith) {
|
||||
|
||||
double lngHour, t, M, L, Lx, RA, RAx, Lquadrant, RAquadrant, sinDec, cosDec, cosH, H, T, UT, UTx;
|
||||
|
||||
/* step 1: First calculate the day of the year
|
||||
int N=theday - date(1,1,theday.year()) + 1;
|
||||
*/
|
||||
|
||||
/* step 2: convert the longitude to hour value and calculate an approximate time */
|
||||
lngHour= longitude / 15;
|
||||
|
||||
/* use 18 for sunset instead of 6 */
|
||||
t = (double)N + ((6 - lngHour) / 24);
|
||||
|
||||
/* step 3: calculate the sun's mean anomaly */
|
||||
M = (0.9856 * t) - 3.289;
|
||||
|
||||
/* step 4: calculate the sun's true longitude */
|
||||
L = M + (1.916 * sin(to_rad(M))) + (0.020 * sin (to_rad(2 * M))) + 282.634;
|
||||
while (L<0)
|
||||
{
|
||||
Lx=L+360;
|
||||
assert (Lx != L); /* askingtheguru: realy needed? */
|
||||
L = Lx;
|
||||
}
|
||||
while (L>=360)
|
||||
{
|
||||
Lx=L-360;
|
||||
assert (Lx != L); /* askingtheguru: realy needed? */
|
||||
L = Lx;
|
||||
}
|
||||
|
||||
/* step 5a: calculate the sun's right ascension */
|
||||
RA = to_deg(atan (0.91764 * tan(to_rad(L))));
|
||||
|
||||
while (RA<0)
|
||||
{
|
||||
RAx=RA+360;
|
||||
assert (RAx != RA); /* askingtheguru: realy needed? */
|
||||
RA = RAx;
|
||||
}
|
||||
while (RA>=360)
|
||||
{
|
||||
RAx=RA-360;
|
||||
assert (RAx != RA); /* askingtheguru: realy needed? */
|
||||
RA = RAx;
|
||||
}
|
||||
|
||||
/* step 5b: right ascension value needs to be in the same quadrant as L */
|
||||
Lquadrant = floor(L/90)*90;
|
||||
RAquadrant = floor(RA/90)*90;
|
||||
RA=RA+(Lquadrant - RAquadrant);
|
||||
|
||||
/* step 5c: right ascension value needs to be converted into hours */
|
||||
RA/=15;
|
||||
|
||||
/* step 6: calculate the sun's declination */
|
||||
sinDec = 0.39782 * sin(to_rad(L));
|
||||
cosDec = cos(asin(sinDec));
|
||||
|
||||
/* step 7a: calculate the sun's local hour angle */
|
||||
cosH = (cos(to_rad(zenith)) - (sinDec * sin(to_rad(latitude)))) / (cosDec * cos(to_rad(latitude)));
|
||||
|
||||
if (cosH > 1){
|
||||
/* throw doesnthappen(); */
|
||||
}
|
||||
|
||||
/*
|
||||
FOR SUNSET use the following instead of the above if statement.
|
||||
// if (cosH < -1)
|
||||
*/
|
||||
|
||||
/* step 7b: finish calculating H and convert into hours */
|
||||
H = 360 - to_deg(acos(cosH));
|
||||
|
||||
/* FOR SUNSET remove "360 - " from the above */
|
||||
|
||||
H=H/15;
|
||||
|
||||
/* step 8: calculate local mean time */
|
||||
T = H + RA - (0.06571 * t) - 6.622;
|
||||
|
||||
/* step 9: convert to UTC */
|
||||
UT = T - lngHour;
|
||||
while (UT<0) {
|
||||
UTx=UT+24;
|
||||
assert (UTx != UT); /* askingtheguru: realy needed? */
|
||||
UT = UTx;
|
||||
}
|
||||
while (UT>=24) {
|
||||
UTx=UT-24;
|
||||
assert (UTx != UT); /* askingtheguru: realy needed? */
|
||||
UT = UTx;
|
||||
}
|
||||
|
||||
return UT;
|
||||
}
|
||||
|
||||
/* {{{ proto mixed sunset(mixed time[, int format][, float latitude][, float longitude][, float zenith,][ float gmt_offset])
|
||||
Returns time of sunset for a given day & location */
|
||||
PHP_FUNCTION(date_sunset)
|
||||
{
|
||||
zval *date;
|
||||
double latitude, longitude, zenith, gmt_offset, ret;
|
||||
int time, N, retformat;
|
||||
char retstr[6];
|
||||
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ldddd", &date, &retformat, &latitude, &longitude, &zenith, &gmt_offset) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
switch(Z_TYPE_P(date)){
|
||||
case IS_LONG:
|
||||
time = Z_LVAL_P(date);
|
||||
break;
|
||||
case IS_STRING:
|
||||
/* todo: more user friendly format */
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "date must be timestamp for now");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
N = idate('z',time,0)+1;
|
||||
|
||||
switch(ZEND_NUM_ARGS()){
|
||||
case 1:
|
||||
retformat = SUNFUNCS_RET_STRING;
|
||||
case 2:
|
||||
latitude = INI_FLT("date.default_latitude");
|
||||
case 3:
|
||||
longitude = INI_FLT("date.default_longitude");
|
||||
case 4:
|
||||
zenith = INI_FLT("date.sunset_zenith");
|
||||
case 5:
|
||||
gmt_offset = idate('Z',time,0)/3600;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = sunset(N, latitude, longitude, zenith) + gmt_offset;
|
||||
|
||||
switch(retformat){
|
||||
case SUNFUNCS_RET_TIMESTAMP:
|
||||
RETURN_LONG((int)(time-(time%(24*3600)))+(int)(60*ret));
|
||||
break;
|
||||
case SUNFUNCS_RET_STRING:
|
||||
N = (int)ret;
|
||||
sprintf(retstr, "%02d:%02d", N,(int)(60*(ret-(double)N)));
|
||||
RETVAL_STRINGL(retstr, 5, 1);
|
||||
break;
|
||||
case SUNFUNCS_RET_DOUBLE:
|
||||
RETURN_DOUBLE(ret);
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid format");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* returns time in UTC */
|
||||
double sunset(long N, double latitude, double longitude, double zenith)
|
||||
{
|
||||
|
||||
double lngHour, t, M, L, Lx, RA, RAx, Lquadrant, RAquadrant, sinDec, cosDec, cosH, H, T, UT, UTx;
|
||||
|
||||
/*
|
||||
//step 1: First calculate the day of the year
|
||||
int N=theday - date(1,1,theday.year()) + 1;
|
||||
*/
|
||||
|
||||
/* step 2: convert the longitude to hour value and calculate an approximate time */
|
||||
lngHour= longitude / 15;
|
||||
|
||||
t = (double)N + ((18 - lngHour) / 24);
|
||||
|
||||
/* step 3: calculate the sun's mean anomaly */
|
||||
M = (0.9856 * t) - 3.289;
|
||||
|
||||
/* step 4: calculate the sun's true longitude */
|
||||
L = M + (1.916 * sin(to_rad(M))) + (0.020 * sin (to_rad(2 * M))) + 282.634;
|
||||
while (L<0)
|
||||
{
|
||||
Lx=L+360;
|
||||
assert (Lx != L); /* askingtheguru: realy needed? */
|
||||
L = Lx;
|
||||
}
|
||||
while (L>=360)
|
||||
{
|
||||
Lx=L-360;
|
||||
assert (Lx != L); /* askingtheguru: realy needed? */
|
||||
L = Lx;
|
||||
}
|
||||
|
||||
/* step 5a: calculate the sun's right ascension */
|
||||
RA = to_deg(atan (0.91764 * tan(to_rad(L))));
|
||||
while (RA<0)
|
||||
{
|
||||
RAx=RA+360;
|
||||
assert (RAx != RA); /* askingtheguru: realy needed? */
|
||||
RA = RAx;
|
||||
}
|
||||
while (RA>=360)
|
||||
{
|
||||
RAx=RA-360;
|
||||
assert (RAx != RA); /* askingtheguru: realy needed? */
|
||||
RA = RAx;
|
||||
}
|
||||
|
||||
/* step 5b: right ascension value needs to be in the same quadrant as L */
|
||||
Lquadrant = floor(L/90)*90;
|
||||
RAquadrant = floor(RA/90)*90;
|
||||
RA=RA+(Lquadrant - RAquadrant);
|
||||
|
||||
/* step 5c: right ascension value needs to be converted into hours */
|
||||
RA/=15;
|
||||
|
||||
/* step 6: calculate the sun's declination */
|
||||
sinDec = 0.39782 * sin(to_rad(L));
|
||||
cosDec = cos(asin(sinDec));
|
||||
|
||||
/* step 7a: calculate the sun's local hour angle */
|
||||
cosH = (cos(to_rad(zenith)) - (sinDec * sin(to_rad(latitude)))) / (cosDec * cos(to_rad(latitude)));
|
||||
|
||||
/*
|
||||
if (cosH < -1)
|
||||
throw doesnthappen();
|
||||
*/
|
||||
|
||||
/* step 7b: finish calculating H and convert into hours */
|
||||
H = to_deg(acos(cosH));
|
||||
H=H/15;
|
||||
|
||||
/* step 8: calculate local mean time */
|
||||
T = H + RA - (0.06571 * t) - 6.622;
|
||||
|
||||
/* step 9: convert to UTC */
|
||||
UT = T - lngHour;
|
||||
while (UT<0) {
|
||||
UTx=UT+24;
|
||||
assert (UTx != UT); /* askingtheguru: realy needed? */
|
||||
UT = UTx;
|
||||
}
|
||||
while (UT>=24) {
|
||||
UTx=UT-24;
|
||||
assert (UTx != UT); /* askingtheguru: realy needed? */
|
||||
UT = UTx;
|
||||
}
|
||||
|
||||
return UT;
|
||||
}
|
31
ext/standard/sunfuncs.h
Normal file
31
ext/standard/sunfuncs.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef SUNFUNCS_H
|
||||
#define SUNFUNCS_H
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define to_rad(degrees) (degrees * M_PI / 180)
|
||||
#define to_rad_with_min(degrees) (degrees + minutes / 60)
|
||||
#define to_deg(rad) (rad * 180 / M_PI)
|
||||
|
||||
|
||||
/* default ini entries: */
|
||||
/* Jerusalem one. */
|
||||
#define DATE_DEFAULT_LATITUDE "31.7667"
|
||||
#define DATE_DEFAULT_LONGITUDE "35.2333"
|
||||
/* on 90'50; common jewish sunset declaration (start of sun body appear) */
|
||||
#define DATE_SUNSET_ZENITH "90.83"
|
||||
/* on 90'50; common jewish sunrise declaration (sun body disappeared) */
|
||||
#define DATE_SUNRISE_ZENITH "90.83"
|
||||
|
||||
#define SUNFUNCS_RET_TIMESTAMP 0
|
||||
#define SUNFUNCS_RET_STRING 1
|
||||
#define SUNFUNCS_RET_DOUBLE 2
|
||||
double sunrise(long N, double latitude, double longitude, double zenith);
|
||||
double sunset(long N, double latitude, double longitude, double zenith);
|
||||
|
||||
PHP_FUNCTION(date_sunrise);
|
||||
PHP_FUNCTION(date_sunset);
|
||||
|
||||
#endif /* SUNFUNCS_H */
|
39
ext/standard/tests/general_functions/sunfuncts.phpt
Normal file
39
ext/standard/tests/general_functions/sunfuncts.phpt
Normal file
@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
idate() function
|
||||
--FILE--
|
||||
<?
|
||||
for($a=1;$a<=12;$a++){
|
||||
echo date_sunrise(mktime(1,1,1,$a,1,2003),SUNFUNCS_RET_TIMESTAMP,31.76670,35.23330,90.83,2)." ";
|
||||
echo date_sunrise(mktime(1,1,1,$a,1,2003),SUNFUNCS_RET_STRING,31.76670,35.23330,90.83,2)." ";
|
||||
echo date_sunrise(mktime(1,1,1,$a,1,2003),SUNFUNCS_RET_DOUBLE,31.76670,35.23330,90.83,2)."\n";
|
||||
|
||||
echo date_sunset(mktime(1,1,1,$a,1,2003),SUNFUNCS_RET_TIMESTAMP,31.76670,35.23330,90.83,2)." ";
|
||||
echo date_sunset(mktime(1,1,1,$a,1,2003),SUNFUNCS_RET_STRING,31.76670,35.23330,90.83,2)." ";
|
||||
echo date_sunset(mktime(1,1,1,$a,1,2003),SUNFUNCS_RET_DOUBLE,31.76670,35.23330,90.83,2)."\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1041293199 06:39 6.6524557618962
|
||||
1041293806 16:46 16.769374867459
|
||||
1043971592 06:32 6.5453702926602
|
||||
1043972233 17:13 17.217524708736
|
||||
1046390766 06:06 6.1156526756851
|
||||
1046391456 17:36 17.6108549623
|
||||
1049069128 05:28 5.4727420290691
|
||||
1049069878 17:58 17.972552584375
|
||||
1051661094 04:54 4.9012299828593
|
||||
1051661898 18:18 18.313688769483
|
||||
1054339474 04:34 4.5744292894498
|
||||
1054340319 18:39 18.656400943241
|
||||
1056931476 04:36 4.6161204505189
|
||||
1056932328 18:48 18.808871657766
|
||||
1059609894 04:54 4.9068825098365
|
||||
1059610715 18:35 18.599286002028
|
||||
1062288314 05:14 5.2368895570738
|
||||
1062289083 18:03 18.060541787879
|
||||
1064880332 05:32 5.542366581139
|
||||
1064881044 17:24 17.411505614917
|
||||
1067558754 05:54 5.9162088420581
|
||||
1067559410 16:50 16.833698570628
|
||||
1070150780 06:20 6.3462215520697
|
||||
1070151395 16:35 16.583589055537
|
30
ext/standard/tests/time/idate.phpt
Normal file
30
ext/standard/tests/time/idate.phpt
Normal file
@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
idate() function
|
||||
--FILE--
|
||||
<?
|
||||
$tmp = "UYzymndjHGhgistwLBIW";
|
||||
for($a=0;$a<strlen($tmp);$a++){
|
||||
echo idate($tmp{$a},1043324459)."\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1043324459
|
||||
2003
|
||||
22
|
||||
3
|
||||
1
|
||||
1
|
||||
23
|
||||
23
|
||||
12
|
||||
12
|
||||
12
|
||||
12
|
||||
20
|
||||
59
|
||||
31
|
||||
4
|
||||
0
|
||||
556
|
||||
0
|
||||
4
|
Loading…
Reference in New Issue
Block a user