- 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)
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)
}
/* }}} */
+/* {{{ 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, ×tamp) == 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;
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);
/* 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 */
--- /dev/null
+--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
#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)
}
/* }}} */
-/* {{{ 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(×tamp);
- break;
- case 2:
- if (zend_get_parameters_ex(2, &format_arg, ×tamp_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(×tamp, &tmbuf);
- } else {
- ta = php_localtime_r(×tamp, &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)
#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 */