From 7b581f6d19957871df502c8563a4eae8e54c15ca Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Mon, 19 Dec 2005 13:00:37 +0000 Subject: [PATCH] - MFH: Merged new timelib, which is a bit more cleverer - MFH: Support "UTC" in strtotime() properly. - MFH: Added astro code, which is going to form the base for the new sunfuncs. --- ext/date/config.m4 | 2 +- ext/date/lib/astro.c | 301 ++++++++++++++++++ ext/date/lib/astro.h | 51 +++ ext/date/lib/parse_date.c | 170 +++++----- ext/date/lib/parse_date.re | 15 +- ext/date/lib/timelib.c | 8 + ext/date/lib/timelib.h | 8 +- ext/date/lib/timezonemap.h | 2 +- ext/date/lib/unixtime2tm.c | 51 ++- ext/date/php_date.c | 46 ++- .../tests/date_default_timezone_get-1.phpt | 8 +- .../tests/date_default_timezone_set-1.phpt | 6 +- ext/date/tests/mktime-2.phpt | 2 +- 13 files changed, 541 insertions(+), 129 deletions(-) create mode 100644 ext/date/lib/astro.c create mode 100644 ext/date/lib/astro.h diff --git a/ext/date/config.m4 b/ext/date/config.m4 index 9e39d4f7e9..cbd732f4ed 100644 --- a/ext/date/config.m4 +++ b/ext/date/config.m4 @@ -5,7 +5,7 @@ sinclude(ext/date/lib/timelib.m4) sinclude(lib/timelib.m4) PHP_DATE_CFLAGS="-I@ext_builddir@/lib" -timelib_sources="lib/dow.c lib/parse_date.c lib/parse_tz.c +timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c" PHP_NEW_EXTENSION(date, php_date.c $timelib_sources, no,, $PHP_DATE_CFLAGS) diff --git a/ext/date/lib/astro.c b/ext/date/lib/astro.c new file mode 100644 index 0000000000..6826238d4a --- /dev/null +++ b/ext/date/lib/astro.c @@ -0,0 +1,301 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2005 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Algorithms are taken from a public domain source by Paul | + | Schlyter, who wrote this in December 1992 | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include +#include +#include "timelib.h" + +#define days_since_2000_Jan_0(y,m,d) \ + (367L*(y)-((7*((y)+(((m)+9)/12)))/4)+((275*(m))/9)+(d)-730530L) + +#ifndef PI + #define PI 3.1415926535897932384 +#endif + +#define RADEG ( 180.0 / PI ) +#define DEGRAD ( PI / 180.0 ) + +/* The trigonometric functions in degrees */ + +#define sind(x) sin((x)*DEGRAD) +#define cosd(x) cos((x)*DEGRAD) +#define tand(x) tan((x)*DEGRAD) + +#define atand(x) (RADEG*atan(x)) +#define asind(x) (RADEG*asin(x)) +#define acosd(x) (RADEG*acos(x)) +#define atan2d(y,x) (RADEG*atan2(y,x)) + + +/* Following are some macros around the "workhorse" function __daylen__ */ +/* They mainly fill in the desired values for the reference altitude */ +/* below the horizon, and also selects whether this altitude should */ +/* refer to the Sun's center or its upper limb. */ + + +#include "astro.h" + +/******************************************************************/ +/* This function reduces any angle to within the first revolution */ +/* by subtracting or adding even multiples of 360.0 until the */ +/* result is >= 0.0 and < 360.0 */ +/******************************************************************/ + +#define INV360 (1.0 / 360.0) + +/*****************************************/ +/* Reduce angle to within 0..360 degrees */ +/*****************************************/ +static double astro_revolution(double x) +{ + return (x - 360.0 * floor(x * INV360)); +} + +/*********************************************/ +/* Reduce angle to within +180..+180 degrees */ +/*********************************************/ +static double astro_rev180( double x ) +{ + return (x - 360.0 * floor(x * INV360 + 0.5)); +} + +/*******************************************************************/ +/* This function computes GMST0, the Greenwich Mean Sidereal Time */ +/* at 0h UT (i.e. the sidereal time at the Greenwhich meridian at */ +/* 0h UT). GMST is then the sidereal time at Greenwich at any */ +/* time of the day. I've generalized GMST0 as well, and define it */ +/* as: GMST0 = GMST - UT -- this allows GMST0 to be computed at */ +/* other times than 0h UT as well. While this sounds somewhat */ +/* contradictory, it is very practical: instead of computing */ +/* GMST like: */ +/* */ +/* GMST = (GMST0) + UT * (366.2422/365.2422) */ +/* */ +/* where (GMST0) is the GMST last time UT was 0 hours, one simply */ +/* computes: */ +/* */ +/* GMST = GMST0 + UT */ +/* */ +/* where GMST0 is the GMST "at 0h UT" but at the current moment! */ +/* Defined in this way, GMST0 will increase with about 4 min a */ +/* day. It also happens that GMST0 (in degrees, 1 hr = 15 degr) */ +/* is equal to the Sun's mean longitude plus/minus 180 degrees! */ +/* (if we neglect aberration, which amounts to 20 seconds of arc */ +/* or 1.33 seconds of time) */ +/* */ +/*******************************************************************/ + +static double astro_GMST0(double d) +{ + double sidtim0; + /* Sidtime at 0h UT = L (Sun's mean longitude) + 180.0 degr */ + /* L = M + w, as defined in sunpos(). Since I'm too lazy to */ + /* add these numbers, I'll let the C compiler do it for me. */ + /* Any decent C compiler will add the constants at compile */ + /* time, imposing no runtime or code overhead. */ + sidtim0 = astro_revolution((180.0 + 356.0470 + 282.9404) + (0.9856002585 + 4.70935E-5) * d); + return sidtim0; +} + +/* This function computes the Sun's position at any instant */ + +/******************************************************/ +/* Computes the Sun's ecliptic longitude and distance */ +/* at an instant given in d, number of days since */ +/* 2000 Jan 0.0. The Sun's ecliptic latitude is not */ +/* computed, since it's always very near 0. */ +/******************************************************/ +static void astro_sunpos(double d, double *lon, double *r) +{ + double M, /* Mean anomaly of the Sun */ + w, /* Mean longitude of perihelion */ + /* Note: Sun's mean longitude = M + w */ + e, /* Eccentricity of Earth's orbit */ + E, /* Eccentric anomaly */ + x, y, /* x, y coordinates in orbit */ + v; /* True anomaly */ + + /* Compute mean elements */ + M = astro_revolution(356.0470 + 0.9856002585 * d); + w = 282.9404 + 4.70935E-5 * d; + e = 0.016709 - 1.151E-9 * d; + + /* Compute true longitude and radius vector */ + E = M + e * RADEG * sind(M) * (1.0 + e * cosd(M)); + x = cosd(E) - e; + y = sqrt(1.0 - e*e) * sind(E); + *r = sqrt(x*x + y*y); /* Solar distance */ + v = atan2d(y, x); /* True anomaly */ + *lon = v + w; /* True solar longitude */ + if (*lon >= 360.0) { + *lon -= 360.0; /* Make it 0..360 degrees */ + } +} + +static void astro_sun_RA_dec(double d, double *RA, double *dec, double *r) +{ + double lon, obl_ecl, x, y, z; + + /* Compute Sun's ecliptical coordinates */ + astro_sunpos(d, &lon, r); + + /* Compute ecliptic rectangular coordinates (z=0) */ + x = *r * cosd(lon); + y = *r * sind(lon); + + /* Compute obliquity of ecliptic (inclination of Earth's axis) */ + obl_ecl = 23.4393 - 3.563E-7 * d; + + /* Convert to equatorial rectangular coordinates - x is unchanged */ + z = y * sind(obl_ecl); + y = y * cosd(obl_ecl); + + /* Convert to spherical coordinates */ + *RA = atan2d(y, x); + *dec = atan2d(z, sqrt(x*x + y*y)); +} + +/** + * Note: timestamp = unixtimestamp (NEEDS to be 00:00:00 UT) + * Eastern longitude positive, Western longitude negative + * Northern latitude positive, Southern latitude negative + * The longitude value IS critical in this function! + * altit = the altitude which the Sun should cross + * Set to -35/60 degrees for rise/set, -6 degrees + * for civil, -12 degrees for nautical and -18 + * degrees for astronomical twilight. + * upper_limb: non-zero -> upper limb, zero -> center + * Set to non-zero (e.g. 1) when computing rise/set + * times, and to zero when computing start/end of + * twilight. + * *rise = where to store the rise time + * *set = where to store the set time + * Both times are relative to the specified altitude, + * and thus this function can be used to compute + * various twilight times, as well as rise/set times + * Return value: 0 = sun rises/sets this day, times stored at + * *trise and *tset. + * +1 = sun above the specified "horizon" 24 hours. + * *trise set to time when the sun is at south, + * minus 12 hours while *tset is set to the south + * time plus 12 hours. "Day" length = 24 hours + * -1 = sun is below the specified "horizon" 24 hours + * "Day" length = 0 hours, *trise and *tset are + * both set to the time when the sun is at south. + * + */ +int timelib_astro_rise_set_altitude(timelib_time *t_loc, double lon, double lat, double altit, int upper_limb, double *h_rise, double *h_set, timelib_sll *ts_rise, timelib_sll *ts_set) +{ + double d, /* Days since 2000 Jan 0.0 (negative before) */ + sr, /* Solar distance, astronomical units */ + sRA, /* Sun's Right Ascension */ + sdec, /* Sun's declination */ + sradius, /* Sun's apparent radius */ + t, /* Diurnal arc */ + tsouth, /* Time when Sun is at south */ + sidtime; /* Local sidereal time */ + timelib_time *t_utc; + timelib_sll timestamp; + + int rc = 0; /* Return cde from function - usually 0 */ + + /* Normalize time */ + t_loc->h = 12; + t_loc->i = t_loc->s = 0; + timelib_update_ts(t_loc, NULL); + + /* Calculate TS belonging to UTC 00:00 of the current day */ + t_utc = timelib_time_ctor(); + t_utc->y = t_loc->y; + t_utc->m = t_loc->m; + t_utc->d = t_loc->d; + t_utc->h = t_utc->i = t_utc->s = 0; + timelib_update_ts(t_utc, NULL); + + /* Compute d of 12h local mean solar time */ + timestamp = t_loc->sse; + d = timelib_ts_to_juliandate(timestamp) - lon/360.0; + + /* Compute local sidereal time of this moment */ + sidtime = astro_revolution(astro_GMST0(d) + 180.0 + lon); + + /* Compute Sun's RA + Decl at this moment */ + astro_sun_RA_dec( d, &sRA, &sdec, &sr ); + + /* Compute time when Sun is at south - in hours UT */ + tsouth = 12.0 - astro_rev180(sidtime - sRA) / 15.0; + + /* Compute the Sun's apparent radius, degrees */ + sradius = 0.2666 / sr; + + /* Do correction to upper limb, if necessary */ + if (upper_limb) { + altit -= sradius; + } + + /* Compute the diurnal arc that the Sun traverses to reach */ + /* the specified altitude altit: */ + { + double cost; + cost = (sind(altit) - sind(lat) * sind(sdec)) / (cosd(lat) * cosd(sdec)); + if (cost >= 1.0) { + rc = -1; + t = 0.0; /* Sun always below altit */ + + *ts_rise = *ts_set = t_utc->sse + (tsouth * 3600); + } else if (cost <= -1.0) { + rc = +1; + t = 12.0; /* Sun always above altit */ + + *ts_rise = t_loc->sse - (12 * 3600); + *ts_set = t_loc->sse + (12 * 3600); + } else { + t = acosd(cost) / 15.0; /* The diurnal arc, hours */ + + /* Store rise and set times - as Unix Timestamp */ + *ts_rise = ((tsouth - t) * 3600) + t_utc->sse; + *ts_set = ((tsouth + t) * 3600) + t_utc->sse; + + *h_rise = (tsouth - t); + *h_set = (tsouth + t); + } + } + + + /* Kill temporary time */ + timelib_time_dtor(t_utc); + + return rc; +} + +double timelib_ts_to_juliandate(timelib_sll ts) +{ + double tmp; + + tmp = ts; + tmp /= 86400; + tmp += 2440587.5; + tmp -= 2451543; + + return tmp; +} diff --git a/ext/date/lib/astro.h b/ext/date/lib/astro.h new file mode 100644 index 0000000000..7b85c76b74 --- /dev/null +++ b/ext/date/lib/astro.h @@ -0,0 +1,51 @@ +/* This macro computes the length of the day, from sunrise to sunset. */ +/* Sunrise/set is considered to occur when the Sun's upper limb is */ +/* 35 arc minutes below the horizon (this accounts for the refraction */ +/* of the Earth's atmosphere). */ +#define day_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -35.0/60.0, 1 ) + +/* This macro computes the length of the day, including civil twilight. */ +/* Civil twilight starts/ends when the Sun's center is 6 degrees below */ +/* the horizon. */ +#define day_civil_twilight_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -6.0, 0 ) + +/* This macro computes the length of the day, incl. nautical twilight. */ +/* Nautical twilight starts/ends when the Sun's center is 12 degrees */ +/* below the horizon. */ +#define day_nautical_twilight_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -12.0, 0 ) + +/* This macro computes the length of the day, incl. astronomical twilight. */ +/* Astronomical twilight starts/ends when the Sun's center is 18 degrees */ +/* below the horizon. */ +#define day_astronomical_twilight_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -18.0, 0 ) + + +/* This macro computes times for sunrise/sunset. */ +/* Sunrise/set is considered to occur when the Sun's upper limb is */ +/* 35 arc minutes below the horizon (this accounts for the refraction */ +/* of the Earth's atmosphere). */ +#define timelib_astro_sun_rise_set(ts,lon,lat,hrise,hset,rise,set) \ + timelib_astro_rise_set_altitude( ts, lon, lat, -35.0/60.0, 1, hrise, hset, rise, set ) + +/* This macro computes the start and end times of civil twilight. */ +/* Civil twilight starts/ends when the Sun's center is 6 degrees below */ +/* the horizon. */ +#define civil_twilight(ts,lon,lat,start,end) \ + timelib_astro_rise_set_altitude( ts, lon, lat, -6.0, 0, start, end ) + +/* This macro computes the start and end times of nautical twilight. */ +/* Nautical twilight starts/ends when the Sun's center is 12 degrees */ +/* below the horizon. */ +#define nautical_twilight(ts,lon,lat,start,end) \ + timelib_astro_rise_set_altitude( ts, lon, lat, -12.0, 0, start, end ) + +/* This macro computes the start and end times of astronomical twilight. */ +/* Astronomical twilight starts/ends when the Sun's center is 18 degrees */ +/* below the horizon. */ +#define astronomical_twilight(ts,lon,lat,start,end) \ + timelib_astro_rise_set_altitude( ts, lon, lat, -18.0, 0, start, end ) + diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index 9d75aad677..c6ad96e969 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.9.11 on Sun Dec 18 21:58:22 2005 */ +/* Generated by re2c 0.9.12.dev on Mon Dec 19 11:52:26 2005 */ #line 1 "ext/date/lib/parse_date.re" /* +----------------------------------------------------------------------+ @@ -173,6 +173,10 @@ static timelib_tz_lookup_table timelib_timezone_fallbackmap[] = { { NULL, 0, 0, NULL }, }; +static timelib_tz_lookup_table timelib_timezone_utc[] = { + { "utc", 0, 0, "UTC" }, +}; + static timelib_relunit const timelib_relunit_lookup[] = { { "sec", TIMELIB_SECOND, 1 }, { "secs", TIMELIB_SECOND, 1 }, @@ -583,10 +587,12 @@ static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffset, in int first_found = 0; timelib_tz_lookup_table *tp, *first_found_elem; timelib_tz_lookup_table *fmp; - - if (gmtoffset == -1 && !strcmp(word, "UTC")) { - goto skip_name_match; + + if (strcasecmp("utc", word) == 0) + { + return timelib_timezone_utc; } + for (tp = timelib_timezone_lookup; tp->name; tp++) { if (strcasecmp(word, tp->name) == 0) { if (!first_found) { @@ -604,7 +610,7 @@ static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffset, in if (first_found) { return first_found_elem; } -skip_name_match: + /* Still didn't find anything, let's find the zone solely based on * offset/isdst then */ for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) { @@ -723,7 +729,7 @@ static int scan(Scanner *s) std: s->tok = cursor; s->len = 0; -#line 832 "ext/date/lib/parse_date.re" +#line 838 "ext/date/lib/parse_date.re" { @@ -762,7 +768,7 @@ std: 0, 0, 0, 0, 0, 0, 0, 0, }; -#line 766 "ext/date/lib/parse_date.c" +#line 772 "ext/date/lib/parse_date.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -854,7 +860,7 @@ yy2: yy3: YYDEBUG(3, *YYCURSOR); -#line 1327 "ext/date/lib/parse_date.re" +#line 1333 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("tzcorrection | tz"); @@ -864,7 +870,7 @@ yy3: TIMELIB_DEINIT; return TIMELIB_TIMEZONE; } -#line 861 "ext/date/lib/parse_date.c" +#line 867 "ext/date/lib/parse_date.c" yy4: YYDEBUG(4, *YYCURSOR); yych = *++YYCURSOR; @@ -982,13 +988,13 @@ yy7: yy8: YYDEBUG(8, *YYCURSOR); -#line 1393 "ext/date/lib/parse_date.re" +#line 1399 "ext/date/lib/parse_date.re" { /* printf("unexpected character: #%d, %c ", *s->tok, *s->tok); */ s->errors++; goto std; } -#line 975 "ext/date/lib/parse_date.c" +#line 981 "ext/date/lib/parse_date.c" yy9: YYDEBUG(9, *YYCURSOR); yyaccept = 0; @@ -2042,11 +2048,11 @@ yy44: yy45: YYDEBUG(45, *YYCURSOR); -#line 1382 "ext/date/lib/parse_date.re" +#line 1388 "ext/date/lib/parse_date.re" { goto std; } -#line 1954 "ext/date/lib/parse_date.c" +#line 1960 "ext/date/lib/parse_date.c" yy46: YYDEBUG(46, *YYCURSOR); yych = *++YYCURSOR; @@ -2058,12 +2064,12 @@ yy47: yy48: YYDEBUG(48, *YYCURSOR); -#line 1387 "ext/date/lib/parse_date.re" +#line 1393 "ext/date/lib/parse_date.re" { s->pos = cursor; s->line++; goto std; } -#line 1965 "ext/date/lib/parse_date.c" +#line 1971 "ext/date/lib/parse_date.c" yy49: YYDEBUG(49, *YYCURSOR); yych = *++YYCURSOR; @@ -2271,7 +2277,7 @@ yy67: yy68: YYDEBUG(68, *YYCURSOR); -#line 1366 "ext/date/lib/parse_date.re" +#line 1372 "ext/date/lib/parse_date.re" { timelib_ull i; DEBUG_OUTPUT("relative"); @@ -2286,7 +2292,7 @@ yy68: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 2146 "ext/date/lib/parse_date.c" +#line 2152 "ext/date/lib/parse_date.c" yy69: YYDEBUG(69, *YYCURSOR); yych = *++YYCURSOR; @@ -3263,7 +3269,7 @@ yy172: yy173: YYDEBUG(173, *YYCURSOR); -#line 1310 "ext/date/lib/parse_date.re" +#line 1316 "ext/date/lib/parse_date.re" { timelib_sll i; int behavior; @@ -3279,7 +3285,7 @@ yy173: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 2923 "ext/date/lib/parse_date.c" +#line 2929 "ext/date/lib/parse_date.c" yy174: YYDEBUG(174, *YYCURSOR); yych = *++YYCURSOR; @@ -5041,7 +5047,7 @@ yy341: yy342: YYDEBUG(342, *YYCURSOR); -#line 1294 "ext/date/lib/parse_date.re" +#line 1300 "ext/date/lib/parse_date.re" { const timelib_relunit* relunit; DEBUG_OUTPUT("daytext"); @@ -5056,7 +5062,7 @@ yy342: TIMELIB_DEINIT; return TIMELIB_WEEKDAY; } -#line 4360 "ext/date/lib/parse_date.c" +#line 4366 "ext/date/lib/parse_date.c" yy343: YYDEBUG(343, *YYCURSOR); yyaccept = 1; @@ -6048,7 +6054,7 @@ yy405: yy406: YYDEBUG(406, *YYCURSOR); -#line 1113 "ext/date/lib/parse_date.re" +#line 1119 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datetextual | datenoyear"); TIMELIB_INIT; @@ -6060,7 +6066,7 @@ yy406: TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 5236 "ext/date/lib/parse_date.c" +#line 5242 "ext/date/lib/parse_date.c" yy407: YYDEBUG(407, *YYCURSOR); yych = *++YYCURSOR; @@ -6271,7 +6277,7 @@ yy427: yy428: YYDEBUG(428, *YYCURSOR); -#line 1338 "ext/date/lib/parse_date.re" +#line 1344 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz"); @@ -6298,7 +6304,7 @@ yy428: TIMELIB_DEINIT; return TIMELIB_SHORTDATE_WITH_TIME; } -#line 5430 "ext/date/lib/parse_date.c" +#line 5436 "ext/date/lib/parse_date.c" yy429: YYDEBUG(429, *YYCURSOR); yyaccept = 7; @@ -6657,7 +6663,7 @@ yy464: yy465: YYDEBUG(465, *YYCURSOR); -#line 1087 "ext/date/lib/parse_date.re" +#line 1093 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenoday"); TIMELIB_INIT; @@ -6669,7 +6675,7 @@ yy465: TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 5727 "ext/date/lib/parse_date.c" +#line 5733 "ext/date/lib/parse_date.c" yy466: YYDEBUG(466, *YYCURSOR); yyaccept = 6; @@ -7042,7 +7048,7 @@ yy490: yy491: YYDEBUG(491, *YYCURSOR); -#line 1225 "ext/date/lib/parse_date.re" +#line 1231 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("pgtextshort"); TIMELIB_INIT; @@ -7054,7 +7060,7 @@ yy491: TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 6060 "ext/date/lib/parse_date.c" +#line 6066 "ext/date/lib/parse_date.c" yy492: YYDEBUG(492, *YYCURSOR); yych = *++YYCURSOR; @@ -8887,7 +8893,7 @@ yy592: yy593: YYDEBUG(593, *YYCURSOR); -#line 1279 "ext/date/lib/parse_date.re" +#line 1285 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("ago"); TIMELIB_INIT; @@ -8901,7 +8907,7 @@ yy593: TIMELIB_DEINIT; return TIMELIB_AGO; } -#line 7703 "ext/date/lib/parse_date.c" +#line 7709 "ext/date/lib/parse_date.c" yy594: YYDEBUG(594, *YYCURSOR); yyaccept = 1; @@ -11235,7 +11241,7 @@ yy702: yy703: YYDEBUG(703, *YYCURSOR); -#line 1126 "ext/date/lib/parse_date.re" +#line 1132 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenoyearrev"); TIMELIB_INIT; @@ -11246,7 +11252,7 @@ yy703: TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 9824 "ext/date/lib/parse_date.c" +#line 9830 "ext/date/lib/parse_date.c" yy704: YYDEBUG(704, *YYCURSOR); yyaccept = 10; @@ -11356,7 +11362,7 @@ yy713: yy714: YYDEBUG(714, *YYCURSOR); -#line 916 "ext/date/lib/parse_date.re" +#line 922 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12"); TIMELIB_INIT; @@ -11372,7 +11378,7 @@ yy714: TIMELIB_DEINIT; return TIMELIB_TIME12; } -#line 9928 "ext/date/lib/parse_date.c" +#line 9934 "ext/date/lib/parse_date.c" yy715: YYDEBUG(715, *YYCURSOR); yych = *++YYCURSOR; @@ -11392,7 +11398,7 @@ yy716: yy717: YYDEBUG(717, *YYCURSOR); -#line 933 "ext/date/lib/parse_date.re" +#line 939 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long"); @@ -11415,7 +11421,7 @@ yy717: TIMELIB_DEINIT; return TIMELIB_TIME24_WITH_ZONE; } -#line 9965 "ext/date/lib/parse_date.c" +#line 9971 "ext/date/lib/parse_date.c" yy718: YYDEBUG(718, *YYCURSOR); yyaccept = 11; @@ -11658,7 +11664,7 @@ yy742: yy743: YYDEBUG(743, *YYCURSOR); -#line 1060 "ext/date/lib/parse_date.re" +#line 1066 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datefull"); TIMELIB_INIT; @@ -11671,7 +11677,7 @@ yy743: TIMELIB_DEINIT; return TIMELIB_DATE_FULL; } -#line 10169 "ext/date/lib/parse_date.c" +#line 10175 "ext/date/lib/parse_date.c" yy744: YYDEBUG(744, *YYCURSOR); yych = *++YYCURSOR; @@ -12306,7 +12312,7 @@ yy811: yy812: YYDEBUG(812, *YYCURSOR); -#line 1074 "ext/date/lib/parse_date.re" +#line 1080 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("pointed date"); TIMELIB_INIT; @@ -12318,7 +12324,7 @@ yy812: TIMELIB_DEINIT; return TIMELIB_DATE_FULL_POINTED; } -#line 10678 "ext/date/lib/parse_date.c" +#line 10684 "ext/date/lib/parse_date.c" yy813: YYDEBUG(813, *YYCURSOR); yych = *++YYCURSOR; @@ -12899,7 +12905,7 @@ yy857: yy858: YYDEBUG(858, *YYCURSOR); -#line 1047 "ext/date/lib/parse_date.re" +#line 1053 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("gnudateshort"); TIMELIB_INIT; @@ -12911,7 +12917,7 @@ yy858: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 11179 "ext/date/lib/parse_date.c" +#line 11185 "ext/date/lib/parse_date.c" yy859: YYDEBUG(859, *YYCURSOR); yyaccept = 12; @@ -12994,7 +13000,7 @@ yy866: yy867: YYDEBUG(867, *YYCURSOR); -#line 1020 "ext/date/lib/parse_date.re" +#line 1026 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("americanshort | american"); TIMELIB_INIT; @@ -13008,7 +13014,7 @@ yy867: TIMELIB_DEINIT; return TIMELIB_AMERICAN; } -#line 11258 "ext/date/lib/parse_date.c" +#line 11264 "ext/date/lib/parse_date.c" yy868: YYDEBUG(868, *YYCURSOR); yyaccept = 13; @@ -13257,7 +13263,7 @@ yy899: yy900: YYDEBUG(900, *YYCURSOR); -#line 1251 "ext/date/lib/parse_date.re" +#line 1257 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("clf"); @@ -13275,7 +13281,7 @@ yy900: TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 11459 "ext/date/lib/parse_date.c" +#line 11465 "ext/date/lib/parse_date.c" yy901: YYDEBUG(901, *YYCURSOR); yyaccept = 14; @@ -13671,7 +13677,7 @@ yy952: yy953: YYDEBUG(953, *YYCURSOR); -#line 1238 "ext/date/lib/parse_date.re" +#line 1244 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("pgtextreverse"); TIMELIB_INIT; @@ -13683,7 +13689,7 @@ yy953: TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 11759 "ext/date/lib/parse_date.c" +#line 11765 "ext/date/lib/parse_date.c" yy954: YYDEBUG(954, *YYCURSOR); yych = *++YYCURSOR; @@ -13816,7 +13822,7 @@ yy964: yy965: YYDEBUG(965, *YYCURSOR); -#line 1270 "ext/date/lib/parse_date.re" +#line 1276 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("year4"); TIMELIB_INIT; @@ -13824,7 +13830,7 @@ yy965: TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 11875 "ext/date/lib/parse_date.c" +#line 11881 "ext/date/lib/parse_date.c" yy966: YYDEBUG(966, *YYCURSOR); yych = *++YYCURSOR; @@ -13960,7 +13966,7 @@ yy973: yy974: YYDEBUG(974, *YYCURSOR); -#line 1100 "ext/date/lib/parse_date.re" +#line 1106 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenodayrev"); TIMELIB_INIT; @@ -13972,7 +13978,7 @@ yy974: TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 12002 "ext/date/lib/parse_date.c" +#line 12008 "ext/date/lib/parse_date.c" yy975: YYDEBUG(975, *YYCURSOR); yych = *++YYCURSOR; @@ -14181,7 +14187,7 @@ yy993: yy994: YYDEBUG(994, *YYCURSOR); -#line 1206 "ext/date/lib/parse_date.re" +#line 1212 "ext/date/lib/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweek"); @@ -14199,7 +14205,7 @@ yy994: TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 12189 "ext/date/lib/parse_date.c" +#line 12195 "ext/date/lib/parse_date.c" yy995: YYDEBUG(995, *YYCURSOR); ++YYCURSOR; @@ -14207,7 +14213,7 @@ yy995: yy996: YYDEBUG(996, *YYCURSOR); -#line 1187 "ext/date/lib/parse_date.re" +#line 1193 "ext/date/lib/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweekday"); @@ -14225,7 +14231,7 @@ yy996: TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 12211 "ext/date/lib/parse_date.c" +#line 12217 "ext/date/lib/parse_date.c" yy997: YYDEBUG(997, *YYCURSOR); yych = *++YYCURSOR; @@ -14294,7 +14300,7 @@ yy999: yy1000: YYDEBUG(1000, *YYCURSOR); -#line 1174 "ext/date/lib/parse_date.re" +#line 1180 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("pgydotd"); TIMELIB_INIT; @@ -14306,7 +14312,7 @@ yy1000: TIMELIB_DEINIT; return TIMELIB_PG_YEARDAY; } -#line 12284 "ext/date/lib/parse_date.c" +#line 12290 "ext/date/lib/parse_date.c" yy1001: YYDEBUG(1001, *YYCURSOR); yych = *++YYCURSOR; @@ -14412,7 +14418,7 @@ yy1006: yy1007: YYDEBUG(1007, *YYCURSOR); -#line 1138 "ext/date/lib/parse_date.re" +#line 1144 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("datenocolon"); TIMELIB_INIT; @@ -14423,7 +14429,7 @@ yy1007: TIMELIB_DEINIT; return TIMELIB_DATE_NOCOLON; } -#line 12383 "ext/date/lib/parse_date.c" +#line 12389 "ext/date/lib/parse_date.c" yy1008: YYDEBUG(1008, *YYCURSOR); yych = *++YYCURSOR; @@ -14521,7 +14527,7 @@ yy1017: yy1018: YYDEBUG(1018, *YYCURSOR); -#line 1150 "ext/date/lib/parse_date.re" +#line 1156 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx"); @@ -14544,7 +14550,7 @@ yy1018: TIMELIB_DEINIT; return TIMELIB_XMLRPC_SOAP; } -#line 12482 "ext/date/lib/parse_date.c" +#line 12488 "ext/date/lib/parse_date.c" yy1019: YYDEBUG(1019, *YYCURSOR); yych = *++YYCURSOR; @@ -15160,7 +15166,7 @@ yy1108: yy1109: YYDEBUG(1109, *YYCURSOR); -#line 1035 "ext/date/lib/parse_date.re" +#line 1041 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("iso8601date | iso8601dateslash | dateslash"); TIMELIB_INIT; @@ -15171,7 +15177,7 @@ yy1109: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 12927 "ext/date/lib/parse_date.c" +#line 12933 "ext/date/lib/parse_date.c" yy1110: YYDEBUG(1110, *YYCURSOR); yyaccept = 19; @@ -16124,7 +16130,7 @@ yy1200: yy1201: YYDEBUG(1201, *YYCURSOR); -#line 957 "ext/date/lib/parse_date.re" +#line 963 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("gnunocolon"); TIMELIB_INIT; @@ -16145,7 +16151,7 @@ yy1201: TIMELIB_DEINIT; return TIMELIB_GNU_NOCOLON; } -#line 13715 "ext/date/lib/parse_date.c" +#line 13721 "ext/date/lib/parse_date.c" yy1202: YYDEBUG(1202, *YYCURSOR); yych = *++YYCURSOR; @@ -16242,7 +16248,7 @@ yy1208: yy1209: YYDEBUG(1209, *YYCURSOR); -#line 1002 "ext/date/lib/parse_date.re" +#line 1008 "ext/date/lib/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("iso8601nocolon"); @@ -16259,7 +16265,7 @@ yy1209: TIMELIB_DEINIT; return TIMELIB_ISO_NOCOLON; } -#line 13813 "ext/date/lib/parse_date.c" +#line 13819 "ext/date/lib/parse_date.c" yy1210: YYDEBUG(1210, *YYCURSOR); yyaccept = 22; @@ -16578,7 +16584,7 @@ yy1233: yy1234: YYDEBUG(1234, *YYCURSOR); -#line 892 "ext/date/lib/parse_date.re" +#line 898 "ext/date/lib/parse_date.re" { timelib_ull i; @@ -16601,7 +16607,7 @@ yy1234: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 14099 "ext/date/lib/parse_date.c" +#line 14105 "ext/date/lib/parse_date.c" yy1235: YYDEBUG(1235, *YYCURSOR); yych = *++YYCURSOR; @@ -16683,7 +16689,7 @@ yy1242: yy1243: YYDEBUG(1243, *YYCURSOR); -#line 880 "ext/date/lib/parse_date.re" +#line 886 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("tomorrow"); TIMELIB_INIT; @@ -16694,7 +16700,7 @@ yy1243: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 14174 "ext/date/lib/parse_date.c" +#line 14180 "ext/date/lib/parse_date.c" yy1244: YYDEBUG(1244, *YYCURSOR); yych = *++YYCURSOR; @@ -16708,7 +16714,7 @@ yy1245: yy1246: YYDEBUG(1246, *YYCURSOR); -#line 870 "ext/date/lib/parse_date.re" +#line 876 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("midnight | today"); TIMELIB_INIT; @@ -16717,7 +16723,7 @@ yy1246: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 14191 "ext/date/lib/parse_date.c" +#line 14197 "ext/date/lib/parse_date.c" yy1247: YYDEBUG(1247, *YYCURSOR); yych = *++YYCURSOR; @@ -16812,7 +16818,7 @@ yy1254: yy1255: YYDEBUG(1255, *YYCURSOR); -#line 849 "ext/date/lib/parse_date.re" +#line 855 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("now"); TIMELIB_INIT; @@ -16820,7 +16826,7 @@ yy1255: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 14276 "ext/date/lib/parse_date.c" +#line 14282 "ext/date/lib/parse_date.c" yy1256: YYDEBUG(1256, *YYCURSOR); yych = *++YYCURSOR; @@ -16846,7 +16852,7 @@ yy1257: yy1258: YYDEBUG(1258, *YYCURSOR); -#line 858 "ext/date/lib/parse_date.re" +#line 864 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("noon"); TIMELIB_INIT; @@ -16857,7 +16863,7 @@ yy1258: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 14307 "ext/date/lib/parse_date.c" +#line 14313 "ext/date/lib/parse_date.c" yy1259: YYDEBUG(1259, *YYCURSOR); yych = *++YYCURSOR; @@ -16926,7 +16932,7 @@ yy1266: yy1267: YYDEBUG(1267, *YYCURSOR); -#line 837 "ext/date/lib/parse_date.re" +#line 843 "ext/date/lib/parse_date.re" { DEBUG_OUTPUT("yesterday"); TIMELIB_INIT; @@ -16937,10 +16943,10 @@ yy1267: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 14369 "ext/date/lib/parse_date.c" +#line 14375 "ext/date/lib/parse_date.c" } } -#line 1398 "ext/date/lib/parse_date.re" +#line 1404 "ext/date/lib/parse_date.re" } diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index 50f2c0e9d5..63d70e593c 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -171,6 +171,10 @@ static timelib_tz_lookup_table timelib_timezone_fallbackmap[] = { { NULL, 0, 0, NULL }, }; +static timelib_tz_lookup_table timelib_timezone_utc[] = { + { "utc", 0, 0, "UTC" }, +}; + static timelib_relunit const timelib_relunit_lookup[] = { { "sec", TIMELIB_SECOND, 1 }, { "secs", TIMELIB_SECOND, 1 }, @@ -581,10 +585,11 @@ static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffset, in int first_found = 0; timelib_tz_lookup_table *tp, *first_found_elem; timelib_tz_lookup_table *fmp; - - if (gmtoffset == -1 && !strcmp(word, "UTC")) { - goto skip_name_match; + + if (strcasecmp("utc", word) == 0) { + return timelib_timezone_utc; } + for (tp = timelib_timezone_lookup; tp->name; tp++) { if (strcasecmp(word, tp->name) == 0) { if (!first_found) { @@ -602,7 +607,7 @@ static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffset, in if (first_found) { return first_found_elem; } -skip_name_match: + /* Still didn't find anything, let's find the zone solely based on * offset/isdst then */ for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) { @@ -792,7 +797,7 @@ pointeddate = day "." month "." year; datefull = day ([ -.])* monthtext ([ -.])* year; datenoday = monthtext ([ -.])* year4; datenodayrev = year4 ([ -.])* monthtext; -datetextual = monthtext ([ -.])* day [,.stndrh ]* year; +datetextual = monthtext ([ -.])* day [,.stndrh ]* year; datenoyear = monthtext ([ -.])* day [,.stndrh ]*; datenoyearrev = day ([ -.])* monthtext; datenocolon = year4 monthlz daylz; diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c index 18bcf9fc11..be0dc1a91e 100644 --- a/ext/date/lib/timelib.c +++ b/ext/date/lib/timelib.c @@ -20,6 +20,7 @@ #include "timelib.h" #include +#include #define TIMELIB_TIME_FREE(m) \ if (m) { \ @@ -139,6 +140,13 @@ signed long timelib_date_to_int(timelib_time *d, int *error) return (signed long) d->sse; } +void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec) +{ + *hour = floor(h); + *min = floor((h - *hour) * 60); + *sec = (h - *hour - ((float) *min / 60)) * 3600; +} + void timelib_dump_date(timelib_time *d, int options) { if ((options & 2) == 2) { diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index 127275903e..0b2f0fe0ee 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -62,7 +62,7 @@ void timelib_update_ts(timelib_time* time, timelib_tzinfo* tzi); /* From unixtime2tm.c */ int timelib_apply_localtime(timelib_time *t, unsigned int localtime); void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts); -void timelib_unixtime2local(timelib_time *tm, timelib_sll ts, timelib_tzinfo* tz); +void timelib_unixtime2local(timelib_time *tm, timelib_sll ts); void timelib_update_from_sse(timelib_time *tm); void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz); @@ -91,4 +91,10 @@ void timelib_time_offset_dtor(timelib_time_offset* t); signed long timelib_date_to_int(timelib_time *d, int *error); void timelib_dump_date(timelib_time *d, int options); +void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec); + +/* from astro.c */ +double timelib_ts_to_juliandate(timelib_sll ts); +int timelib_astro_rise_set_altitude(timelib_time *time, double lon, double lat, double altit, int upper_limb, double *h_rise, double *h_set, timelib_sll *ts_rise, timelib_sll *ts_set); + #endif diff --git a/ext/date/lib/timezonemap.h b/ext/date/lib/timezonemap.h index 2cb341f6f3..84997964d6 100644 --- a/ext/date/lib/timezonemap.h +++ b/ext/date/lib/timezonemap.h @@ -885,7 +885,6 @@ { "gmt", 0, 0, "GB" }, { "gmt", 0, 0, "GB-Eire" }, { "gmt", 0, 0, "GMT" }, - { "utc", 0, 0, "UTC" }, { "gmt", 0, 0, "Iceland" }, { "gst", 0, 14400, "Asia/Dubai" }, { "gst", 0, 14400, "Asia/Bahrain" }, @@ -1622,6 +1621,7 @@ { "r", 0, -18000, NULL }, { "s", 0, -21600, NULL }, { "t", 0, -25200, NULL }, + { "utc", 0, 0, "UTC" }, { "u", 0, -28800, NULL }, { "v", 0, -32400, NULL }, { "w", 0, -36000, NULL }, diff --git a/ext/date/lib/unixtime2tm.c b/ext/date/lib/unixtime2tm.c index 984187d324..0187abbcfb 100644 --- a/ext/date/lib/unixtime2tm.c +++ b/ext/date/lib/unixtime2tm.c @@ -121,7 +121,6 @@ void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts) tm->sse_uptodate = 1; tm->tim_uptodate = 1; tm->is_localtime = 0; - tm->have_zone = 0; } void timelib_update_from_sse(timelib_time *tm) @@ -138,8 +137,6 @@ void timelib_update_from_sse(timelib_time *tm) timelib_unixtime2gmt(tm, tm->sse - (tm->z * 60)); - tm->is_localtime = 1; - tm->have_zone = 1; tm->z = z; tm->dst = dst; goto cleanup; @@ -165,25 +162,45 @@ cleanup: tm->have_zone = 1; } -void timelib_unixtime2local(timelib_time *tm, timelib_sll ts, timelib_tzinfo* tz) +void timelib_unixtime2local(timelib_time *tm, timelib_sll ts) { timelib_time_offset *gmt_offset; + timelib_tzinfo *tz = tm->tz_info; - gmt_offset = timelib_get_time_zone_info(ts, tz); - timelib_unixtime2gmt(tm, ts + gmt_offset->offset); + tm->is_localtime = 1; + tm->have_zone = 1; - /* we need to reset the sse here as unixtime2gmt modifies it */ - tm->sse = ts; - tm->dst = gmt_offset->is_dst; - tm->z = gmt_offset->offset; - tm->tz_info = tz; + switch (tm->zone_type) { + case TIMELIB_ZONETYPE_ABBR: + case TIMELIB_ZONETYPE_OFFSET: { + int z = tm->z; + signed int dst = tm->dst; + + timelib_unixtime2gmt(tm, ts - (tm->z * 60)); - timelib_time_tz_abbr_update(tm, gmt_offset->abbr); - timelib_time_offset_dtor(gmt_offset); + tm->z = z; + tm->dst = dst; + break; + } - tm->is_localtime = 1; - tm->have_zone = 1; - tm->zone_type = TIMELIB_ZONETYPE_ID; + case TIMELIB_ZONETYPE_ID: + gmt_offset = timelib_get_time_zone_info(ts, tz); + timelib_unixtime2gmt(tm, ts + gmt_offset->offset); + + /* we need to reset the sse here as unixtime2gmt modifies it */ + tm->sse = ts; + tm->dst = gmt_offset->is_dst; + tm->z = gmt_offset->offset; + tm->tz_info = tz; + + timelib_time_tz_abbr_update(tm, gmt_offset->abbr); + timelib_time_offset_dtor(gmt_offset); + break; + + default: + tm->is_localtime = 0; + tm->have_zone = 0; + } } void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz) @@ -225,7 +242,7 @@ int timelib_apply_localtime(timelib_time *t, unsigned int localtime) return -1; } - timelib_unixtime2local(t, t->sse, t->tz_info); + timelib_unixtime2local(t, t->sse); } else { /* Converting from local time to GMT time */ DEBUG(printf("Converting from local time to GMT time\n");); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index cb4bbb1553..67f8e22bf1 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -590,7 +590,9 @@ PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localt if (localtime) { tzi = get_timezone_info(TSRMLS_C); - timelib_unixtime2local(t, ts, tzi); + t->tz_info = tzi; + t->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(t, ts); } else { tzi = NULL; timelib_unixtime2gmt(t, ts); @@ -618,7 +620,9 @@ PHPAPI int php_idate(char format, time_t ts, int localtime) if (!localtime) { TSRMLS_FETCH(); tzi = get_timezone_info(TSRMLS_C); - timelib_unixtime2local(t, ts, tzi); + t->tz_info = tzi; + t->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(t, ts); } else { tzi = NULL; timelib_unixtime2gmt(t, ts); @@ -797,13 +801,17 @@ PHP_FUNCTION(strtotime) snprintf(initial_ts, 24, "@%lu", preset_ts); t = timelib_strtotime(initial_ts, strlen(initial_ts), &error1, DATE_TIMEZONEDB); /* we ignore the error here, as this should never fail */ timelib_update_ts(t, tzi); - timelib_unixtime2local(now, t->sse, tzi); + now->tz_info = tzi; + now->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(now, t->sse); timelib_time_dtor(t); efree(initial_ts); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", ×, &time_len) != FAILURE) { /* We have no initial timestamp */ now = timelib_time_ctor(); - timelib_unixtime2local(now, (timelib_sll) time(NULL), tzi); + now->tz_info = tzi; + now->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(now, (timelib_sll) time(NULL)); } else { RETURN_FALSE; } @@ -814,7 +822,7 @@ PHP_FUNCTION(strtotime) ts = timelib_date_to_int(t, &error2); /* if tz_info is not a copy, avoid double free */ - if (now->tz_info != tzi) { + if (now->tz_info != tzi && now->tz_info) { timelib_tzinfo_dtor(now->tz_info); } if (t->tz_info != tzi) { @@ -851,7 +859,9 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) timelib_unixtime2gmt(now, (timelib_sll) time(NULL)); } else { tzi = get_timezone_info(TSRMLS_C); - timelib_unixtime2local(now, (timelib_sll) time(NULL), tzi); + now->tz_info = tzi; + now->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(now, (timelib_sll) time(NULL)); } /* Fill in the new data */ switch (ZEND_NUM_ARGS()) { @@ -987,7 +997,9 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt) timelib_unixtime2gmt(ts, (timelib_sll) timestamp); } else { tzi = get_timezone_info(TSRMLS_C); - timelib_unixtime2local(ts, (timelib_sll) timestamp, tzi); + ts->tz_info = tzi; + ts->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(ts, (timelib_sll) timestamp); } ta.tm_sec = ts->s; ta.tm_min = ts->i; @@ -1080,7 +1092,9 @@ PHP_FUNCTION(localtime) tzi = get_timezone_info(TSRMLS_C); ts = timelib_time_ctor(); - timelib_unixtime2local(ts, (timelib_sll) timestamp, tzi); + ts->tz_info = tzi; + ts->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(ts, (timelib_sll) timestamp); array_init(return_value); @@ -1124,7 +1138,9 @@ PHP_FUNCTION(getdate) tzi = get_timezone_info(TSRMLS_C); ts = timelib_time_ctor(); - timelib_unixtime2local(ts, (timelib_sll) timestamp, tzi); + ts->tz_info = tzi; + ts->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(ts, (timelib_sll) timestamp); array_init(return_value); @@ -1239,14 +1255,14 @@ static void date_object_free_storage_date(void *object TSRMLS_DC) static void date_object_free_storage_timezone(void *object TSRMLS_DC) { - php_date_obj *intern = (php_date_obj *)object; - + php_timezone_obj *intern = (php_timezone_obj *)object; + if (intern->std.properties) { zend_hash_destroy(intern->std.properties); efree(intern->std.properties); intern->std.properties = NULL; } - + efree(object); } @@ -1296,7 +1312,9 @@ PHP_FUNCTION(date_create) } now = timelib_time_ctor(); - timelib_unixtime2local(now, (timelib_sll) time(NULL), tzi); + now->tz_info = tzi; + now->zone_type = TIMELIB_ZONETYPE_ID; + timelib_unixtime2local(now, (timelib_sll) time(NULL)); timelib_fill_holes(dateobj->time, now, 0); timelib_update_ts(dateobj->time, tzi); @@ -1390,7 +1408,7 @@ PHP_FUNCTION(date_timezone_set) timelib_tzinfo_dtor(dateobj->time->tz_info); } timelib_set_timezone(dateobj->time, timelib_tzinfo_clone(tzobj->tz)); - timelib_unixtime2local(dateobj->time, dateobj->time->sse, dateobj->time->tz_info); + timelib_unixtime2local(dateobj->time, dateobj->time->sse); } PHP_FUNCTION(date_offset_get) diff --git a/ext/date/tests/date_default_timezone_get-1.phpt b/ext/date/tests/date_default_timezone_get-1.phpt index 1771413735..d3508290ad 100644 --- a/ext/date/tests/date_default_timezone_get-1.phpt +++ b/ext/date/tests/date_default_timezone_get-1.phpt @@ -9,8 +9,8 @@ date.timezone= echo date('e'), "\n"; ?> --EXPECTF-- -Strict Standards: date_default_timezone_get(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'Europe/London' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_get-1.php on line 3 -Europe/London +Strict Standards: date_default_timezone_get(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'UTC' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_get-1.php on line 3 +UTC -Strict Standards: date(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'Europe/London' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_get-1.php on line 4 -Europe/London \ No newline at end of file +Strict Standards: date(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'UTC' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_get-1.php on line 4 +UTC diff --git a/ext/date/tests/date_default_timezone_set-1.phpt b/ext/date/tests/date_default_timezone_set-1.phpt index 90916e9238..78face70a7 100644 --- a/ext/date/tests/date_default_timezone_set-1.phpt +++ b/ext/date/tests/date_default_timezone_set-1.phpt @@ -18,11 +18,11 @@ date.timezone= echo date(DATE_ISO8601, $date4), "\n"; ?> --EXPECTF-- -Strict Standards: strtotime(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'Europe/London' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_set-1.php on line 3 +Strict Standards: strtotime(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'UTC' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_set-1.php on line 3 -Strict Standards: strtotime(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'Europe/London' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_set-1.php on line 4 +Strict Standards: strtotime(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We selected 'UTC' for 'UTC/0.0/no DST' instead in %sdate_default_timezone_set-1.php on line 4 America/Indiana/Knox 2005-01-12T03:00:00-0500 -2005-07-12T02:00:00-0500 +2005-07-12T03:00:00-0500 2005-01-12T08:00:00-0500 2005-07-12T08:00:00-0500 diff --git a/ext/date/tests/mktime-2.phpt b/ext/date/tests/mktime-2.phpt index def140f3a0..aa259b577c 100644 --- a/ext/date/tests/mktime-2.phpt +++ b/ext/date/tests/mktime-2.phpt @@ -3,7 +3,7 @@ mktime() [2] --INI-- error_reporting=2047 --FILE-- -