]> granicus.if.org Git - php/commitdiff
- Fixed bug #33532 (Different output for strftime() and date()).
authorDerick Rethans <derick@php.net>
Sun, 3 Jul 2005 19:14:55 +0000 (19:14 +0000)
committerDerick Rethans <derick@php.net>
Sun, 3 Jul 2005 19:14:55 +0000 (19:14 +0000)
- Re-implemented checkdate(), strftime() and gmstrftime() with the new timelib
  code.

NEWS
ext/date/php_date.c
ext/date/php_date.h
ext/date/tests/bug33532.phpt [new file with mode: 0644]
ext/standard/basic_functions.c
ext/standard/datetime.c
ext/standard/datetime.h

diff --git a/NEWS b/NEWS
index bbe96ef5e6b52e28d6b087e3b04dcd485a101a6c..ddfaee6df576161b336f9aba7829b1e7e03b0b3a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ PHP                                                                        NEWS
 - Added date_timezone_set() function to set the timezone that the date
   functions will use. (Derick)
 - Implemented feature request #33452 (Year belonging to ISO week). (Derick)
+- Fixed bug #33532 (Different output for strftime() and date()). (Derick)
 - Fixed bug #33523 (Memory leak in xmlrpc_encode_request()). (Ilia)
 - Fixed bug #33491 (crash after extending MySQLi internal class). (Tony)
 - Fixed bug #33475 (cURL handle is not closed on curl_close(). (Ilia)
index 795ec8b8e5f74793d2e649fbbf217d2873eb5b80..f91ad7cdecf03edf6323c1aca01ed4bbe0e0aec9 100644 (file)
@@ -32,6 +32,9 @@ function_entry date_functions[] = {
        PHP_FE(date, NULL)
        PHP_FE(gmdate, NULL)
        PHP_FE(mktime, NULL)
+       PHP_FE(checkdate, NULL)
+       PHP_FE(gmstrftime, NULL)
+       PHP_FE(strftime, NULL)
        PHP_FE(gmmktime, NULL)
        PHP_FE(strtotime, NULL)
        PHP_FE(date_timezone_set, NULL)
@@ -520,6 +523,124 @@ PHP_FUNCTION(gmmktime)
 }
 /* }}} */
 
+/* {{{ proto bool checkdate(int month, int day, int year)
+   Returns true(1) if it is a valid date in gregorian calendar */
+PHP_FUNCTION(checkdate)
+{
+       long m, d, y;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &m, &d, &y) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (y < 1 || y > 32767 || m < 1 || m > 12 || d < 1 || d > timelib_days_in_month(y, m)) {
+               RETURN_FALSE;
+       }
+       RETURN_TRUE;    /* True : This month, day, year arguments are valid */
+}
+/* }}} */
+
+#if HAVE_STRFTIME
+/* {{{ php_strftime
+ */
+PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
+{
+       char                *format, *buf;
+       int                  format_len;
+       long                 timestamp;
+       struct tm            ta;
+       int                  max_reallocs = 5;
+       size_t               buf_len = 64, real_len;
+       timelib_time        *ts;
+       timelib_tzinfo      *tzi;
+       timelib_time_offset *offset;
+
+       timestamp = (long) time(NULL);
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &timestamp) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (format_len == 0) {
+               RETURN_FALSE;
+       }
+
+       ts = timelib_time_ctor();
+       if (gmt) {
+               tzi = NULL;
+               timelib_unixtime2gmt(ts, (timelib_sll) timestamp);
+       } else {
+               tzi = get_timezone_info(TSRMLS_C);
+               timelib_unixtime2local(ts, (timelib_sll) timestamp, tzi);
+       }
+       ta.tm_sec   = ts->s;
+       ta.tm_min   = ts->i;
+       ta.tm_hour  = ts->h;
+       ta.tm_mday  = ts->d;
+       ta.tm_mon   = ts->m - 1;
+       ta.tm_year  = ts->y - 1900;
+       ta.tm_wday  = timelib_day_of_week(ts->y, ts->m, ts->d);
+       ta.tm_yday  = timelib_day_of_year(ts->y, ts->m, ts->d);
+       if (gmt) {
+               ta.tm_isdst = 0;
+#if HAVE_TM_GMTOFF
+               ta.tm_gmtoff = 0;
+#endif
+#if HAVE_TM_ZONE
+               ta.tm_zone = "GMT";
+#endif
+       } else {
+               offset = timelib_get_time_zone_info(timestamp, tzi);
+
+               ta.tm_isdst = offset->is_dst;
+#if HAVE_TM_GMTOFF
+               ta.tm_gmtoff = offset->offset;
+#endif
+#if HAVE_TM_ZONE
+               ta.tm_zone = offset->abbr;
+#endif
+       }
+
+       buf = (char *) emalloc(buf_len);
+       while ((real_len=strftime(buf, buf_len, format, &ta))==buf_len || real_len==0) {
+               buf_len *= 2;
+               buf = (char *) erealloc(buf, buf_len);
+               if (!--max_reallocs) {
+                       break;
+               }
+       }
+
+       timelib_time_dtor(ts);
+       if (gmt) {
+               timelib_time_offset_dtor(offset);
+       }
+
+       if (real_len && real_len != buf_len) {
+               buf = (char *) erealloc(buf, real_len + 1);
+               RETURN_STRINGL(buf, real_len, 0);
+       }
+       efree(buf);
+       RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string strftime(string format [, int timestamp])
+   Format a local time/date according to locale settings */
+PHP_FUNCTION(strftime)
+{
+       _php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto string gmstrftime(string format [, int timestamp])
+   Format a GMT/UCT time/date according to locale settings */
+PHP_FUNCTION(gmstrftime)
+{
+       _php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+#endif
+
 PHP_FUNCTION(date_timezone_set)
 {
        char *zone;
index 470546f485b9211500a7f4938158a25ccd7f408a..3da151f541ccb5a36f08bb127491d2e5156d14c9 100644 (file)
@@ -31,6 +31,13 @@ PHP_FUNCTION(strtotime);
 PHP_FUNCTION(mktime);
 PHP_FUNCTION(gmmktime);
 
+PHP_FUNCTION(checkdate);
+
+#if HAVE_STRFTIME
+PHP_FUNCTION(strftime);
+PHP_FUNCTION(gmstrftime);
+#endif
+
 PHP_FUNCTION(date_timezone_set);
 PHP_FUNCTION(date_timezone_get);
 
@@ -54,5 +61,9 @@ ZEND_END_MODULE_GLOBALS(date)
 /* Backwards compability wrapper */
 signed long php_parse_date(char *string, signed long *now);
 PHPAPI static void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt);
+#if HAVE_STRFTIME
+#define _php_strftime php_strftime
+PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gm);
+#endif
 
 #endif /* PHP_DATE_H */
diff --git a/ext/date/tests/bug33532.phpt b/ext/date/tests/bug33532.phpt
new file mode 100644 (file)
index 0000000..21244af
--- /dev/null
@@ -0,0 +1,37 @@
+--TEST--
+Bug #33532 (Different output for strftime() and date())
+--INI--
+error_reporting=2047
+--FILE--
+<?php
+putenv("TZ=");
+setlocale(LC_ALL, 'C');
+
+print "TZ has NOT been set\n";
+print "Should strftime==datestr? Strftime seems to assume GMT tStamp.\n";
+$input = "10:00:00 AM July 1 2005";
+print "input    " . $input . "\n";
+$tStamp = strtotime($input);
+print "strftime " . strftime("%r %B%e %Y %Z %z", $tStamp) . "\n";
+print "datestr  " . date ("H:i:s A F j Y T", $tStamp) . "\n";
+
+print "\nSetting TZ\n";
+putenv("TZ=Australia/Sydney");
+$input = "10:00:00 AM July 1 2005";
+print "input    " . $input . "\n";
+$tStamp = strtotime($input);
+print "strftime " . strftime("%r %B%e %Y %Z %z", $tStamp) . "\n";
+print "datestr  " . date ("H:i:s A F j Y T", $tStamp) . "\n";
+
+?>
+--EXPECT--
+TZ has NOT been set
+Should strftime==datestr? Strftime seems to assume GMT tStamp.
+input    10:00:00 AM July 1 2005
+strftime 10:00:00 AM July 1 2005 UTC +0000
+datestr  10:00:00 AM July 1 2005 UTC
+
+Setting TZ
+input    10:00:00 AM July 1 2005
+strftime 10:00:00 AM July 1 2005 EST +1000
+datestr  10:00:00 AM July 1 2005 EST
index e86b7262956882bed0f299e5fe1531b08ccf3a95..6203334a3ae553fb0fd0657bc6e3365c3c876632 100644 (file)
@@ -172,15 +172,10 @@ function_entry basic_functions[] = {
 #if HAVE_STRPTIME
        PHP_FE(strptime,                                                                                                                NULL)
 #endif
-#if HAVE_STRFTIME
-       PHP_FE(strftime,                                                                                                                NULL)
-       PHP_FE(gmstrftime,                                                                                                              NULL)
-#endif
 
        PHP_FE(idate,                                                                                                                   NULL)
        PHP_FE(getdate,                                                                                                                 NULL)
        PHP_FE(localtime,                                                                                                               NULL)
-       PHP_FE(checkdate,                                                                                                               NULL)
 
        PHP_FE(flush,                                                                                                                   NULL)
        PHP_FE(wordwrap,                                                                                                                NULL)
index 5e1933f5e9d2ab07944a20fd3a045efb023ce43d..8a2ceecf17403efff22c59fd2a9a1f887152153b 100644 (file)
@@ -353,105 +353,6 @@ PHPAPI char *php_std_date(time_t t TSRMLS_DC)
 }
 /* }}} */
 
-/* {{{ proto bool checkdate(int month, int day, int year)
-   Returns true(1) if it is a valid date in gregorian calendar */
-PHP_FUNCTION(checkdate)
-{
-       long m, d, y;
-
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &m, &d, &y) == FAILURE) {
-               RETURN_FALSE;
-       }
-
-       if (y < 1 || y > 32767 || m < 1 || m > 12 || d < 1 || d > phpday_tab[isleap(y)][m - 1]) {
-               RETURN_FALSE;
-       }
-       RETURN_TRUE;    /* True : This month, day, year arguments are valid */
-}
-/* }}} */
-
-#if HAVE_STRFTIME
-/* {{{ _php_strftime
- */
-PHPAPI void _php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gm)
-{
-       pval **format_arg, **timestamp_arg;
-       char *format, *buf;
-       time_t timestamp;
-       struct tm *ta, tmbuf;
-       int max_reallocs = 5;
-       size_t buf_len=64, real_len;
-
-       switch (ZEND_NUM_ARGS()) {
-               case 1:
-                       if (zend_get_parameters_ex(1, &format_arg)==FAILURE) {
-                               RETURN_FALSE;
-                       }
-                       time(&timestamp);
-                       break;
-               case 2:
-                       if (zend_get_parameters_ex(2, &format_arg, &timestamp_arg)==FAILURE) {
-                               RETURN_FALSE;
-                       }
-                       convert_to_long_ex(timestamp_arg);
-                       timestamp = Z_LVAL_PP(timestamp_arg);
-                       break;
-               default:
-                       WRONG_PARAM_COUNT;
-                       break;
-       }
-
-       convert_to_string_ex(format_arg);
-       if (Z_STRLEN_PP(format_arg)==0) {
-               RETURN_FALSE;
-       }
-#ifdef PHP_WIN32
-       if (timestamp < 0) {
-               RETURN_FALSE;
-       }
-#endif
-       format = Z_STRVAL_PP(format_arg);
-       if (gm) {
-               ta = php_gmtime_r(&timestamp, &tmbuf);
-       } else {
-               ta = php_localtime_r(&timestamp, &tmbuf);
-       }
-
-       buf = (char *) emalloc(buf_len);
-       while ((real_len=strftime(buf, buf_len, format, ta))==buf_len || real_len==0) {
-               buf_len *= 2;
-               buf = (char *) erealloc(buf, buf_len);
-               if (!--max_reallocs) {
-                       break;
-               }
-       }
-       
-       if (real_len && real_len != buf_len) {
-               buf = (char *) erealloc(buf, real_len + 1);
-               RETURN_STRINGL(buf, real_len, 0);
-       }
-       efree(buf);
-       RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto string strftime(string format [, int timestamp])
-   Format a local time/date according to locale settings */
-PHP_FUNCTION(strftime)
-{
-       _php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
-}
-/* }}} */
-
-/* {{{ proto string gmstrftime(string format [, int timestamp])
-   Format a GMT/UCT time/date according to locale settings */
-PHP_FUNCTION(gmstrftime)
-{
-       _php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
-}
-/* }}} */
-
-#endif
 
 #if HAVE_STRPTIME
 /* {{{ proto string strptime(string timestamp, string format)
index 4c1e39fb50d394123f5e6b675133314294617f56..f7c57815ca47de54e92b1f0b1cc9bae9c74b521a 100644 (file)
@@ -30,15 +30,8 @@ PHP_FUNCTION(checkdate);
 #if HAVE_STRPTIME
 PHP_FUNCTION(strptime);
 #endif 
-#if HAVE_STRFTIME
-PHP_FUNCTION(strftime);
-PHP_FUNCTION(gmstrftime);
-#endif
 
 PHPAPI int php_idate(char format, int timestamp, int gm);
 PHPAPI char *php_std_date(time_t t TSRMLS_DC);
-#if HAVE_STRFTIME
-PHPAPI void _php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gm);
-#endif
 
 #endif /* DATETIME_H */