]> granicus.if.org Git - php/commitdiff
Fixed bug #35425 (idate() function ignores timezone settings).
authorIlia Alshanetsky <iliaa@php.net>
Tue, 29 Nov 2005 20:19:56 +0000 (20:19 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Tue, 29 Nov 2005 20:19:56 +0000 (20:19 +0000)
NEWS
ext/date/php_date.c
ext/date/php_date.h
ext/date/tests/bug35425.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 d4c204a001de7878ab1cd845283db67bfa581166..d4b03e831e11a6c0b1175c5eedc88b86e6710e29 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ PHP                                                                        NEWS
 - Fixed bug #35431 (PDO crashes when using LAZY fetch with fetchAll). (Wez)
 - Fixed bug #35430 (PDO crashes on incorrect FETCH_FUNC use). (Tony)
 - Fixed bug #35427 (str_word_count() handles '-' incorrectly). (Ilia)
+- Fixed bug #35425 (idate() function ignores timezone settings). (Ilia)
 - Fixed bug #35422 (strtotime() does not parse times with UTC as timezone).
   (Ilia)
 - Fixed bug #35414 (strtotime() no longer works with ordinal suffix). (Ilia)
index 149f44ca3054832e2b70950ed38ad258060f6987..6eae37b0ab4ac511ba36e0df86ed77f2c313957d 100644 (file)
@@ -594,6 +594,104 @@ PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localt
 }
 /* }}} */
 
+/* {{{ php_idate
+ */
+PHPAPI int php_idate(char format, time_t ts, int localtime)
+{
+       timelib_time   *t;
+       timelib_tzinfo *tzi;
+       int retval = -1;
+       timelib_time_offset *offset;
+       timelib_sll isoweek, isoyear;
+
+       t = timelib_time_ctor();
+
+       if (!localtime) {
+               TSRMLS_FETCH();
+               tzi = get_timezone_info(TSRMLS_C);
+               timelib_unixtime2local(t, ts, tzi);
+       } else {
+               tzi = NULL;
+               timelib_unixtime2gmt(t, ts);
+       }
+
+       if (!localtime) {
+               if (t->zone_type == TIMELIB_ZONETYPE_ABBR) {
+                       offset = timelib_time_offset_ctor();
+                       offset->offset = (t->z - (t->dst * 60)) * -60;
+                       offset->leap_secs = 0;
+                       offset->is_dst = t->dst;
+                       offset->abbr = strdup(t->tz_abbr);
+               } else if (t->zone_type == TIMELIB_ZONETYPE_OFFSET) {
+                       offset = timelib_time_offset_ctor();
+                       offset->offset = (t->z - (t->dst * 60)) * -60;
+                       offset->leap_secs = 0;
+                       offset->is_dst = t->dst;
+                       offset->abbr = malloc(9); /* GMT±xxxx\0 */
+                       snprintf(offset->abbr, 9, "GMT%c%02d%02d", 
+                                                 !localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
+                                                 !localtime ? abs(offset->offset / 3600) : 0,
+                                                 !localtime ? abs((offset->offset % 3600) / 60) : 0 );
+               } else {
+                       offset = timelib_get_time_zone_info(t->sse, t->tz_info);
+               }
+       }
+
+       timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear);
+
+       switch (format) {
+               /* day */
+               case 'd': case 'j': retval = (int) t->d; break;
+
+               case 'w': retval = (int) timelib_day_of_week(t->y, t->m, t->d); break;
+               case 'z': retval = (int) timelib_day_of_year(t->y, t->m, t->d); break;
+
+               /* week */
+               case 'W': retval = (int) isoweek; break; /* iso weeknr */
+
+               /* month */
+               case 'm': case 'n': retval = (int) t->m; break;
+               case 't': retval = (int) timelib_days_in_month(t->y, t->m); break;
+
+               /* year */
+               case 'L': retval = (int) timelib_is_leap((int) t->y); break;
+               case 'y': retval = (int) (t->y % 100); break;
+               case 'Y': retval = (int) t->y; break;
+
+               /* Swatch Beat a.k.a. Internet Time */
+               case 'B':
+                       retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864);                  
+                       while (retval < 0) {
+                               retval += 1000;
+                       }
+                       retval = retval % 1000;
+                       break;
+
+               /* time */
+               case 'g': case 'h': retval = (int) ((t->h % 12) ? (int) t->h % 12 : 12); break;
+               case 'H': case 'G': retval = (int) t->h; break;
+               case 'i': retval = (int) t->i; break;
+               case 's': retval = (int) t->s; break;
+
+               /* timezone */
+               case 'I': retval = (int) (!localtime ? offset->is_dst : 0); break;
+               case 'Z': retval = (int) (!localtime ? offset->offset : 0); break;
+
+               case 'U': retval = (int) t->sse; break;
+               default:
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized date format token.");
+                       break;
+       }
+
+       if (!localtime) {
+               timelib_time_offset_dtor(offset);
+       }
+       timelib_time_dtor(t);
+
+       return retval;
+}
+/* }}} */
+
 /* {{{ proto string date(string format [, long timestamp])
    Format a local date/time */
 PHP_FUNCTION(date)
@@ -610,6 +708,31 @@ PHP_FUNCTION(gmdate)
 }
 /* }}} */
 
+/* {{{ proto int idate(string format [, int timestamp])
+   Format a local time/date as integer */
+PHP_FUNCTION(idate)
+{
+       char   *format;
+       int     format_len;
+       time_t  ts;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (format_len != 1) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "idate format is one char");
+               RETURN_FALSE;
+       }
+
+       if (ZEND_NUM_ARGS() == 1) {
+               ts = time(NULL);
+       }
+
+       RETURN_LONG(php_idate(format[0], ts, 0));
+}
+/* }}} */
+
 /* {{{ php_date_set_tzdb - NOT THREADSAFE */
 PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb)
 {
index 08a03931d4d107020a6c2a1cc98ef0cb4e5edca9..4fb8d4c9dc837e23cfa1e8c65dbe93c9e6f4c275 100644 (file)
@@ -91,6 +91,7 @@ ZEND_END_MODULE_GLOBALS(date)
 /* Backwards compability wrapper */
 signed long php_parse_date(char *string, signed long *now);
 PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt);
+PHPAPI int php_idate(char format, time_t ts, int localtime);
 #if HAVE_STRFTIME
 #define _php_strftime php_strftime
 PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gm);
diff --git a/ext/date/tests/bug35425.phpt b/ext/date/tests/bug35425.phpt
new file mode 100644 (file)
index 0000000..4259b49
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Bug #35425 (idate() function ignores timezone settings)
+--FILE--
+<?php
+putenv('TZ=America/Montreal');
+
+$time = mktime(1,1,1,1,1,2005);
+foreach (array('B','d','h','H','i','I','L','m','s','t','U','w','W','y','Y','z','Z') as $v) {
+       var_dump(idate($v, $time));
+}
+
+?>
+--EXPECT--
+int(292)
+int(1)
+int(1)
+int(1)
+int(1)
+int(0)
+int(0)
+int(1)
+int(1)
+int(31)
+int(1104559261)
+int(6)
+int(53)
+int(5)
+int(2005)
+int(0)
+int(-18000)
index df5933f1a5a857091ea63c9c7db322fdf1eb53e4..a4e1ced714b0705c47fdc130cb4fb4a76a300156 100644 (file)
@@ -177,8 +177,6 @@ function_entry basic_functions[] = {
        PHP_FE(strptime,                                                                                                                NULL)
 #endif
 
-       PHP_FE(idate,                                                                                                                   NULL)
-
        PHP_FE(flush,                                                                                                                   NULL)
        PHP_FE(wordwrap,                                                                                                                NULL)
        PHP_FE(htmlspecialchars,                                                                                                NULL)
index 8f4c54109923404ea06207af8de045949ad2e57f..77139133fc9f25e7d3940b54fe71e1c1cc9feea4 100644 (file)
@@ -53,163 +53,6 @@ char *day_short_names[] = {
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
 };
 
-#if !defined(HAVE_TM_ZONE) && !defined(_TIMEZONE) && !defined(HAVE_DECLARED_TIMEZONE)
-#ifdef NETWARE
-#define timezone    _timezone   /* timezone is called '_timezone' in new version of LibC */
-#endif
-extern time_t timezone;
-extern int daylight;
-#endif
-
-static int phpday_tab[2][12] = {
-       {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
-       {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
-};
-
-#define isleap(year) ((((year) % 4) == 0 && ((year) % 100) != 0) || ((year) % 400)==0)
-#define YEAR_BASE 1900
-
-/* {{{ php_idate
- */
-PHPAPI int php_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) */
-                       if ((yd <= 7 - fd) && fd > 3) {                 /* week is a last year week (52 or 53) */
-                               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)
-{
-       zval **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, &timestamp) == 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 = php_idate(Z_STRVAL_PP(format)[0], t, 0);
-       RETURN_LONG(ret);
-}
-/* }}} */
-
 /* {{{ php_std_date
    Return date string in standard format for http headers */
 PHPAPI char *php_std_date(time_t t TSRMLS_DC)
index 5c125ccfb82497a3feb61147223711182cdb7211..70a29a91731879ed6d6d58b4d19dd27e62fe6c8d 100644 (file)
 #ifndef DATETIME_H
 #define DATETIME_H
 
-PHP_FUNCTION(time);
-PHP_FUNCTION(idate);
-PHP_FUNCTION(localtime);
-PHP_FUNCTION(getdate);
-PHP_FUNCTION(checkdate);
 #if HAVE_STRPTIME
 PHP_FUNCTION(strptime);
 #endif 
 
-PHPAPI int php_idate(char format, int timestamp, int gm);
 PHPAPI char *php_std_date(time_t t TSRMLS_DC);
 
 #endif /* DATETIME_H */