derick Sun Jul 3 10:27:32 2005 EDT
Added files:
/php-src/ext/date/tests bug30096.phpt
Modified files:
/php-src NEWS
/php-src/ext/standard basic_functions.c datetime.c datetime.h
/php-src/ext/standard/tests/time 003.phpt bug27719.phpt mktime.phpt
/php-src/ext/date php_date.c php_date.h
Log:
- Fixed bug #30096 (gmmktime does not return the corrent time).
- Re-implemented mktime and gmmktime with new date time library.
- Added testcase for bug #30096, updated test cases for E_STRICT warning of
is_dst parameter usage for mktime/gmmktime.
http://cvs.php.net/diff.php/php-src/NEWS?r1=1.1972&r2=1.1973&ty=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.1972 php-src/NEWS:1.1973
--- php-src/NEWS:1.1972 Sat Jul 2 19:04:34 2005
+++ php-src/NEWS Sun Jul 3 10:27:31 2005
@@ -19,6 +19,7 @@
- Fixed bug #30828 (debug_backtrace() reports incorrect class in overridden
methods). (Dmitry)
- Fixed bug #30519 (Interface not existing says Class not found). (Dmitry)
+- Fixed bug #30096 (gmmktime does not return the corrent time). (Derick)
- Fixed bug #30052 (Crash on shutdown after odbc_pconnect()). (Edin)
- Fixed bug #28377 (debug_backtrace is intermittently passing args). (Dmitry)
- Fixed bug #27268 (Bad references accentuated by clone). (Dmitry)
http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.721&r2=1.722&ty=u
Index: php-src/ext/standard/basic_functions.c
diff -u php-src/ext/standard/basic_functions.c:1.721
php-src/ext/standard/basic_functions.c:1.722
--- php-src/ext/standard/basic_functions.c:1.721 Thu Jun 30 17:38:06 2005
+++ php-src/ext/standard/basic_functions.c Sun Jul 3 10:27:31 2005
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: basic_functions.c,v 1.721 2005/06/30 21:38:06 derick Exp $ */
+/* $Id: basic_functions.c,v 1.722 2005/07/03 14:27:31 derick Exp $ */
#include "php.h"
#include "php_streams.h"
@@ -169,8 +169,6 @@
PHP_FE(time_sleep_until,
NULL)
#endif
PHP_FE(time,
NULL)
- PHP_FE(mktime,
NULL)
- PHP_FE(gmmktime,
NULL)
#if HAVE_STRPTIME
PHP_FE(strptime,
NULL)
#endif
http://cvs.php.net/diff.php/php-src/ext/standard/datetime.c?r1=1.130&r2=1.131&ty=u
Index: php-src/ext/standard/datetime.c
diff -u php-src/ext/standard/datetime.c:1.130
php-src/ext/standard/datetime.c:1.131
--- php-src/ext/standard/datetime.c:1.130 Thu Jun 30 17:38:06 2005
+++ php-src/ext/standard/datetime.c Sun Jul 3 10:27:31 2005
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: datetime.c,v 1.130 2005/06/30 21:38:06 derick Exp $ */
+/* $Id: datetime.c,v 1.131 2005/07/03 14:27:31 derick Exp $ */
#if HAVE_STRPTIME
#define _XOPEN_SOURCE
@@ -77,210 +77,6 @@
}
/* }}} */
-/* {{{ php_mktime
- */
-PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm)
-{
- pval **arguments[7];
- struct tm *ta, tmbuf;
- time_t t, seconds;
- int i, gmadjust, arg_count = ZEND_NUM_ARGS();
- int is_dst = -1, chgsecs = 0;
- long val;
-
- if (arg_count > 7 || zend_get_parameters_array_ex(arg_count, arguments)
== FAILURE) {
- WRONG_PARAM_COUNT;
- }
- /* convert supplied arguments to longs */
- for (i = 0; i < arg_count; i++) {
- convert_to_long_ex(arguments[i]);
- }
- t = time(NULL);
-#ifdef HAVE_TZSET
- tzset();
-#endif
- /*
- ** Set default time parameters with local time values,
- ** EVEN when some GMT time parameters are specified!
- ** This may give strange result, with PHP gmmktime(0, 0, 0),
- ** which is assumed to return GMT midnight time
- ** for today (in localtime), so that the result time may be
- ** AFTER or BEFORE the current time.
- ** May be we should initialize tn using gmtime(), so that
- ** default parameters for PHP gmmktime would be the current
- ** GMT time values...
- */
- ta = php_localtime_r(&t, &tmbuf);
-
- /* Let DST be unknown. mktime() should compute the right value
- ** and behave correctly. Unless the user overrides this.
- */
- ta->tm_isdst = -1;
-
- /*
- ** Now change date values with supplied parameters.
- */
- switch(arg_count) {
- case 7: /* daylight saving time flag */
-#ifdef PHP_WIN32
- if (daylight > 0) {
- ta->tm_isdst = is_dst = Z_LVAL_PP(arguments[6]);
- } else {
- ta->tm_isdst = is_dst = 0;
- }
-#else
- ta->tm_isdst = is_dst = Z_LVAL_PP(arguments[6]);
-#endif
- /* fall-through */
- case 6: /* year */
- /* special case:
- a zero in year, month and day is considered illegal
- as it would be interpreted as 30.11.1999 otherwise
- */
- if ( ( Z_LVAL_PP(arguments[5])==0)
- &&(Z_LVAL_PP(arguments[4])==0)
- &&(Z_LVAL_PP(arguments[3])==0)
- ) {
- RETURN_LONG(-1);
- }
-
- /*
- ** Accept parameter in range 0..1000 interpreted as 1900..2900
- ** (if 100 is given, it means year 2000)
- ** or in range 1001..9999 interpreted as is (this will store
- ** negative tm_year for years in range 1001..1899)
- ** This function is then Y2K ready, and accepts a wide range of
- ** dates including the whole gregorian calendar.
- ** But it cannot represent ancestral dates prior to year 1001.
- ** Additionally, input parameters of 0..70 are mapped to
100..170
- */
- if (Z_LVAL_PP(arguments[5]) < 70)
- ta->tm_year = Z_LVAL_PP(arguments[5]) + 100;
- else
- ta->tm_year = Z_LVAL_PP(arguments[5])
- - ((Z_LVAL_PP(arguments[5]) > 1000) ? 1900 : 0);
- /* fall-through */
- case 5: /* day in month (1-based) */
- val = (*arguments[4])->value.lval;
- if (val < 1) {
- chgsecs += (1-val) * 60*60*24;
- val = 1;
- }
- ta->tm_mday = val;
- /* fall-through */
- case 4: /* month (zero-based) */
- val = (*arguments[3])->value.lval - 1;
- while (val < 0) {
- val += 12; ta->tm_year--;
- }
- ta->tm_mon = val;
- /* fall-through */
- case 3: /* second */
- val = (*arguments[2])->value.lval;
- if (val < 1) {
- chgsecs += (1-val); val = 1;
- }
- ta->tm_sec = val;
- /* fall-through */
- case 2: /* minute */
- val = (*arguments[1])->value.lval;
- if (val < 1) {
- chgsecs += (1-val) * 60; val = 1;
- }
- ta->tm_min = val;
- /* fall-through */
- case 1: /* hour */
- val = (*arguments[0])->value.lval;
- /*
- We avoid midnight and a couple of hours after midnight here
to work around
- various OS-level bugs in mktime and specifically daylight
savings time issues
- in many mktime implementation.
- See bugs #27533 and #27719 for more info.
- */
- if (val < 4) {
- chgsecs += (4-val) * 60*60; val = 4;
- }
- ta->tm_hour = val;
- /* fall-through */
- case 0:
- break;
- }
-
- t = mktime(ta);
-
-#ifdef PHP_WIN32
- if (t - chgsecs < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Windows does not
support negative values for this function");
- RETURN_LONG(-1);
- }
-#endif
-
- seconds = t - chgsecs;
-
- /*
- Here we check to see if the chgsecs fuzz factor we applied caused us
to
- move from dst to non-dst or vice-versa. If so we adjust accordingly
to
- avoid being off by an hour on the dst changeover date.
- */
- if (is_dst == -1) {
- struct tm t1, t2;
- t1 = *localtime(&t);
- t2 = *localtime(&seconds);
-
- if (t1.tm_isdst != t2.tm_isdst) {
- seconds += (t1.tm_isdst == 1) ? 3600 : -3600;
- ta = localtime(&seconds);
- }
-
- /*
- If the user didn't specify whether the timestamp passed in
was dst or not
- then we fill it in based on the dst setting at the evaluated
timestamp
- at the current TZ
- */
- is_dst = ta->tm_isdst;
- }
-
- if (gm) {
-#if HAVE_TM_GMTOFF
- /*
- ** mktime(ta) very nicely just filled ta->tm_gmtoff with
- ** the exactly right value for adjustment if we want GMT.
- */
- gmadjust = ta->tm_gmtoff;
-#else
- /*
- ** If correcting for daylight savings time, we set the adjustment to
- ** the value of timezone - 3600 seconds.
- */
-#ifdef __CYGWIN__
- gmadjust = -(is_dst ? _timezone - 3600 : _timezone);
-#else
- gmadjust = -(is_dst ? timezone - 3600 : timezone);
-#endif
-#endif
- seconds += gmadjust;
- }
-
- RETURN_LONG(seconds);
-}
-/* }}} */
-
-/* {{{ proto int mktime(int hour, int min, int sec, int mon, int day, int year)
- Get UNIX timestamp for a date */
-PHP_FUNCTION(mktime)
-{
- php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
-}
-/* }}} */
-
-/* {{{ proto int gmmktime(int hour, int min, int sec, int mon, int day, int
year)
- Get UNIX timestamp for a GMT date */
-PHP_FUNCTION(gmmktime)
-{
- php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
-}
-/* }}} */
-
/* {{{ php_idate
*/
PHPAPI int php_idate(char format, int timestamp, int gm)
http://cvs.php.net/diff.php/php-src/ext/standard/datetime.h?r1=1.20&r2=1.21&ty=u
Index: php-src/ext/standard/datetime.h
diff -u php-src/ext/standard/datetime.h:1.20
php-src/ext/standard/datetime.h:1.21
--- php-src/ext/standard/datetime.h:1.20 Thu Jun 30 17:38:06 2005
+++ php-src/ext/standard/datetime.h Sun Jul 3 10:27:31 2005
@@ -17,14 +17,12 @@
+----------------------------------------------------------------------+
*/
-/* $Id: datetime.h,v 1.20 2005/06/30 21:38:06 derick Exp $ */
+/* $Id: datetime.h,v 1.21 2005/07/03 14:27:31 derick Exp $ */
#ifndef DATETIME_H
#define DATETIME_H
PHP_FUNCTION(time);
-PHP_FUNCTION(mktime);
-PHP_FUNCTION(gmmktime);
PHP_FUNCTION(idate);
PHP_FUNCTION(localtime);
PHP_FUNCTION(getdate);
@@ -39,7 +37,6 @@
PHPAPI int php_idate(char format, int timestamp, int gm);
PHPAPI char *php_std_date(time_t t TSRMLS_DC);
-PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm);
#if HAVE_STRFTIME
PHPAPI void _php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gm);
#endif
http://cvs.php.net/diff.php/php-src/ext/standard/tests/time/003.phpt?r1=1.4&r2=1.5&ty=u
Index: php-src/ext/standard/tests/time/003.phpt
diff -u php-src/ext/standard/tests/time/003.phpt:1.4
php-src/ext/standard/tests/time/003.phpt:1.5
--- php-src/ext/standard/tests/time/003.phpt:1.4 Wed May 19 04:45:23 2004
+++ php-src/ext/standard/tests/time/003.phpt Sun Jul 3 10:27:31 2005
@@ -1,5 +1,7 @@
--TEST--
Check for mktime with out-of-range parameters
+--INI--
+error_reporting=2047
--FILE--
<?php
# MacOS/X libc implementation doesn't treat out-of-range values
http://cvs.php.net/diff.php/php-src/ext/standard/tests/time/bug27719.phpt?r1=1.5&r2=1.6&ty=u
Index: php-src/ext/standard/tests/time/bug27719.phpt
diff -u php-src/ext/standard/tests/time/bug27719.phpt:1.5
php-src/ext/standard/tests/time/bug27719.phpt:1.6
--- php-src/ext/standard/tests/time/bug27719.phpt:1.5 Thu Jun 30 17:38:06 2005
+++ php-src/ext/standard/tests/time/bug27719.phpt Sun Jul 3 10:27:31 2005
@@ -1,7 +1,9 @@
--TEST--
Bug #27719: mktime returns incorrect timestamp for dst days
+--INI--
+error_reporting=2047
--FILE--
-<?php /* $Id: bug27719.phpt,v 1.5 2005/06/30 21:38:06 derick Exp $ */
+<?php /* $Id: bug27719.phpt,v 1.6 2005/07/03 14:27:31 derick Exp $ */
putenv("TZ=EST"); // No DST
$a = mktime(0, 0, 0, 4, 4, 2004, 0);
$b = mktime(0, 0, 0, 4, 4, 2004, 1);
http://cvs.php.net/diff.php/php-src/ext/standard/tests/time/mktime.phpt?r1=1.5&r2=1.6&ty=u
Index: php-src/ext/standard/tests/time/mktime.phpt
diff -u php-src/ext/standard/tests/time/mktime.phpt:1.5
php-src/ext/standard/tests/time/mktime.phpt:1.6
--- php-src/ext/standard/tests/time/mktime.phpt:1.5 Tue Mar 30 20:00:55 2004
+++ php-src/ext/standard/tests/time/mktime.phpt Sun Jul 3 10:27:31 2005
@@ -1,7 +1,9 @@
--TEST--
mktime()
+--INI--
+error_reporting=2047
--FILE--
-<?php /* $Id: mktime.phpt,v 1.5 2004/03/31 01:00:55 abies Exp $ */
+<?php /* $Id: mktime.phpt,v 1.6 2005/07/03 14:27:31 derick Exp $ */
$timezones = array(
'GMT0',
'Europe/London'
http://cvs.php.net/diff.php/php-src/ext/date/php_date.c?r1=1.20&r2=1.21&ty=u
Index: php-src/ext/date/php_date.c
diff -u php-src/ext/date/php_date.c:1.20 php-src/ext/date/php_date.c:1.21
--- php-src/ext/date/php_date.c:1.20 Sat Jul 2 17:19:25 2005
+++ php-src/ext/date/php_date.c Sun Jul 3 10:27:31 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_date.c,v 1.20 2005/07/02 21:19:25 derick Exp $ */
+/* $Id: php_date.c,v 1.21 2005/07/03 14:27:31 derick Exp $ */
#include "php.h"
#include "php_streams.h"
@@ -31,6 +31,8 @@
function_entry date_functions[] = {
PHP_FE(date, NULL)
PHP_FE(gmdate, NULL)
+ PHP_FE(mktime, NULL)
+ PHP_FE(gmmktime, NULL)
PHP_FE(strtotime, NULL)
PHP_FE(date_timezone_set, NULL)
PHP_FE(date_timezone_get, NULL)
@@ -400,6 +402,105 @@
}
/* }}} */
+PHPAPI static void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
+{
+ long hou, min, sec, mon, day, yea, dst = -1;;
+ timelib_time *now;
+ timelib_tzinfo *tzi;
+ long ts, adjust_seconds = 0;
+ int error;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lllllll", &hou,
&min, &sec, &mon, &day, &yea, &dst) == FAILURE) {
+ RETURN_FALSE;
+ }
+ /* Initialize structure with current time */
+ now = timelib_time_ctor();
+ if (gmt) {
+ timelib_unixtime2gmt(now, (timelib_sll) time(NULL));
+ } else {
+ tzi = get_timezone_info(TSRMLS_C);
+ timelib_unixtime2local(now, (timelib_sll) time(NULL), tzi);
+ }
+ /* Fill in the new data */
+ switch (ZEND_NUM_ARGS()) {
+ case 7:
+ /* break intentionally missing */
+ case 6:
+ now->y = yea;
+ /* break intentionally missing again */
+ case 5:
+ now->d = day;
+ /* break missing intentionally here too */
+ case 4:
+ now->m = mon;
+ /* and here */
+ case 3:
+ now->s = sec;
+ /* yup, this break isn't here on purpose too */
+ case 2:
+ now->i = min;
+ /* last intentionally missing break */
+ case 1:
+ now->h = hou;
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_STRICT, "You should
be using the time() function instead.");
+ }
+ /* Update the timestamp */
+ if (gmt) {
+ timelib_update_ts(now, NULL);
+ } else {
+ timelib_update_ts(now, tzi);
+ }
+ /* Support for the deprecated is_dst parameter */
+ if (dst != -1) {
+ php_error_docref(NULL TSRMLS_CC, E_STRICT, "The is_dst
parameter is deprecated.");
+ if (gmt) {
+ /* GMT never uses DST */
+ if (dst == 1) {
+ adjust_seconds = -3600;
+ }
+ } else {
+ /* Figure out is_dst for current TS */
+ timelib_time_offset *tmp_offset;
+ tmp_offset = timelib_get_time_zone_info(now->sse, tzi);
+ if (dst == 1 && tmp_offset->is_dst == 0) {
+ adjust_seconds = -3600;
+ }
+ if (dst == 0 && tmp_offset->is_dst == 1) {
+ adjust_seconds = +3600;
+ }
+ }
+ }
+ /* Clean up and return */
+ ts = timelib_date_to_int(now, &error);
+ ts += adjust_seconds;
+
+ timelib_time_dtor(now);
+
+ if (error) {
+ RETURN_FALSE;
+ } else {
+ RETURN_LONG(ts);
+ }
+}
+
+/* {{{ proto int mktime(int hour, int min, int sec, int mon, int day, int year)
+ Get UNIX timestamp for a date */
+PHP_FUNCTION(mktime)
+{
+ php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto int gmmktime(int hour, int min, int sec, int mon, int day, int
year)
+ Get UNIX timestamp for a GMT date */
+PHP_FUNCTION(gmmktime)
+{
+ php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
PHP_FUNCTION(date_timezone_set)
{
char *zone;
http://cvs.php.net/diff.php/php-src/ext/date/php_date.h?r1=1.7&r2=1.8&ty=u
Index: php-src/ext/date/php_date.h
diff -u php-src/ext/date/php_date.h:1.7 php-src/ext/date/php_date.h:1.8
--- php-src/ext/date/php_date.h:1.7 Sat Jul 2 17:19:25 2005
+++ php-src/ext/date/php_date.h Sun Jul 3 10:27:31 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_date.h,v 1.7 2005/07/02 21:19:25 derick Exp $ */
+/* $Id: php_date.h,v 1.8 2005/07/03 14:27:31 derick Exp $ */
#ifndef PHP_DATE_H
#define PHP_DATE_H
@@ -27,6 +27,10 @@
PHP_FUNCTION(date);
PHP_FUNCTION(gmdate);
PHP_FUNCTION(strtotime);
+
+PHP_FUNCTION(mktime);
+PHP_FUNCTION(gmmktime);
+
PHP_FUNCTION(date_timezone_set);
PHP_FUNCTION(date_timezone_get);
@@ -49,5 +53,6 @@
/* Backwards compability wrapper */
signed long php_parse_date(char *string, signed long *now);
+PHPAPI static void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt);
#endif /* PHP_DATE_H */
http://cvs.php.net/co.php/php-src/ext/date/tests/bug30096.phpt?r=1.1&p=1
Index: php-src/ext/date/tests/bug30096.phpt
+++ php-src/ext/date/tests/bug30096.phpt
--TEST--
Bug #30096 (gmmktime does not return the corrent time)
--INI--
error_reporting=2047
--FILE--
<?php
echo "no dst --> dst\n";
$ts = -1;
gm_date_check(01,00,00,03,27,2005);
gm_date_check(02,00,00,03,27,2005);
gm_date_check(03,00,00,03,27,2005);
gm_date_check(04,00,00,03,27,2005);
echo "\ndst --> no dst\n";
$ts = -1;
gm_date_check(01,00,00,10,30,2005);
gm_date_check(02,00,00,10,30,2005);
gm_date_check(03,00,00,10,30,2005);
gm_date_check(04,00,00,10,30,2005);
function gm_date_check($hour, $minute, $second, $month, $day, $year) {
global $ts, $tsold;
echo "gmmktime($hour,$minute,$second,$month,$day,$year): ";
$tsold = $ts;
$ts = gmmktime($hour, $minute, $second, $month, $day, $year);
echo $ts, " | gmdate('r', $ts):", gmdate('r', $ts);
if ($tsold > 0) {
echo " | Diff: " . ($ts - $tsold);
}
echo "\n";
}
?>
--EXPECT--
no dst --> dst
gmmktime(1,0,0,3,27,2005): 1111885200 | gmdate('r', 1111885200):Sun, 27 Mar
2005 01:00:00 +0000
gmmktime(2,0,0,3,27,2005): 1111888800 | gmdate('r', 1111888800):Sun, 27 Mar
2005 02:00:00 +0000 | Diff: 3600
gmmktime(3,0,0,3,27,2005): 1111892400 | gmdate('r', 1111892400):Sun, 27 Mar
2005 03:00:00 +0000 | Diff: 3600
gmmktime(4,0,0,3,27,2005): 1111896000 | gmdate('r', 1111896000):Sun, 27 Mar
2005 04:00:00 +0000 | Diff: 3600
dst --> no dst
gmmktime(1,0,0,10,30,2005): 1130634000 | gmdate('r', 1130634000):Sun, 30 Oct
2005 01:00:00 +0000
gmmktime(2,0,0,10,30,2005): 1130637600 | gmdate('r', 1130637600):Sun, 30 Oct
2005 02:00:00 +0000 | Diff: 3600
gmmktime(3,0,0,10,30,2005): 1130641200 | gmdate('r', 1130641200):Sun, 30 Oct
2005 03:00:00 +0000 | Diff: 3600
gmmktime(4,0,0,10,30,2005): 1130644800 | gmdate('r', 1130644800):Sun, 30 Oct
2005 04:00:00 +0000 | Diff: 3600
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php