diff options
Diffstat (limited to 'ext/date/php_date.c')
-rw-r--r-- | ext/date/php_date.c | 642 |
1 files changed, 528 insertions, 114 deletions
diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 280fd27d7..ce64ff9e0 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_date.c,v 1.43.2.45 2006/04/11 18:03:46 derick Exp $ */ +/* $Id: php_date.c,v 1.43.2.45.2.30 2006/09/10 17:01:51 bjori Exp $ */ #include "php.h" #include "php_streams.h" @@ -29,26 +29,142 @@ #include "lib/timelib.h" #include <time.h> +/* {{{ arginfo */ +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_date, 0, 0, 1) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, timestamp) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmdate, 0, 0, 1) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, timestamp) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_idate, 0, 0, 1) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, timestamp) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_strtotime, 0, 0, 1) + ZEND_ARG_INFO(0, time) + ZEND_ARG_INFO(0, now) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_mktime, 0, 0, 0) + ZEND_ARG_INFO(0, hour) + ZEND_ARG_INFO(0, min) + ZEND_ARG_INFO(0, sec) + ZEND_ARG_INFO(0, mon) + ZEND_ARG_INFO(0, day) + ZEND_ARG_INFO(0, year) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmmktime, 0, 0, 0) + ZEND_ARG_INFO(0, hour) + ZEND_ARG_INFO(0, min) + ZEND_ARG_INFO(0, sec) + ZEND_ARG_INFO(0, mon) + ZEND_ARG_INFO(0, day) + ZEND_ARG_INFO(0, year) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_checkdate, 0) + ZEND_ARG_INFO(0, month) + ZEND_ARG_INFO(0, day) + ZEND_ARG_INFO(0, year) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_strftime, 0, 0, 1) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, timestamp) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmstrftime, 0, 0, 1) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, timestamp) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_time, 0) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_localtime, 0, 0, 0) + ZEND_ARG_INFO(0, timestamp) + ZEND_ARG_INFO(0, associative_array) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_getdate, 0, 0, 0) + ZEND_ARG_INFO(0, timestamp) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_date_default_timezone_set, 0) + ZEND_ARG_INFO(0, timezone_identifier) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_date_default_timezone_get, 0) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_date_sunrise, 0, 0, 1) + ZEND_ARG_INFO(0, time) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, latitude) + ZEND_ARG_INFO(0, longitude) + ZEND_ARG_INFO(0, zenith) + ZEND_ARG_INFO(0, gmt_offset) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_date_sunset, 0, 0, 1) + ZEND_ARG_INFO(0, time) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, latitude) + ZEND_ARG_INFO(0, longitude) + ZEND_ARG_INFO(0, zenith) + ZEND_ARG_INFO(0, gmt_offset) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_date_sun_info, 0) + ZEND_ARG_INFO(0, time) + ZEND_ARG_INFO(0, latitude) + ZEND_ARG_INFO(0, longitude) +ZEND_END_ARG_INFO() + +/* }}} */ + /* {{{ Function table */ zend_function_entry date_functions[] = { - PHP_FE(strtotime, NULL) - PHP_FE(date, NULL) - PHP_FE(idate, NULL) - PHP_FE(gmdate, NULL) - PHP_FE(mktime, NULL) - PHP_FE(gmmktime, NULL) - PHP_FE(checkdate, NULL) + PHP_FE(strtotime, arginfo_strtotime) + PHP_FE(date, arginfo_date) + PHP_FE(idate, arginfo_idate) + PHP_FE(gmdate, arginfo_gmdate) + PHP_FE(mktime, arginfo_mktime) + PHP_FE(gmmktime, arginfo_gmmktime) + PHP_FE(checkdate, arginfo_checkdate) #ifdef HAVE_STRFTIME - PHP_FE(strftime, NULL) - PHP_FE(gmstrftime, NULL) + PHP_FE(strftime, arginfo_strftime) + PHP_FE(gmstrftime, arginfo_gmstrftime) #endif - PHP_FE(time, NULL) - PHP_FE(localtime, NULL) - PHP_FE(getdate, NULL) + PHP_FE(time, arginfo_time) + PHP_FE(localtime, arginfo_localtime) + PHP_FE(getdate, arginfo_getdate) -#ifdef EXPERIMENTAL_DATE_SUPPORT /* Advanced Interface */ PHP_FE(date_create, NULL) PHP_FE(date_parse, NULL) @@ -66,24 +182,23 @@ zend_function_entry date_functions[] = { PHP_FE(timezone_name_get, NULL) PHP_FE(timezone_name_from_abbr, NULL) PHP_FE(timezone_offset_get, NULL) - PHP_FE(timezone_transistions_get, NULL) + PHP_FE(timezone_transitions_get, NULL) PHP_FE(timezone_identifiers_list, NULL) PHP_FE(timezone_abbreviations_list, NULL) -#endif /* Options and Configuration */ - PHP_FE(date_default_timezone_set, NULL) - PHP_FE(date_default_timezone_get, NULL) + PHP_FE(date_default_timezone_set, arginfo_date_default_timezone_set) + PHP_FE(date_default_timezone_get, arginfo_date_default_timezone_get) /* Astronomical functions */ - PHP_FE(date_sunrise, NULL) - PHP_FE(date_sunset, NULL) - PHP_FE(date_sun_info, NULL) + PHP_FE(date_sunrise, arginfo_date_sunrise) + PHP_FE(date_sunset, arginfo_date_sunset) + PHP_FE(date_sun_info, arginfo_date_sun_info) {NULL, NULL, NULL} }; -#ifdef EXPERIMENTAL_DATE_SUPPORT zend_function_entry date_funcs_date[] = { + PHP_ME(DateTime, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) ZEND_NAMED_FE(format, ZEND_FN(date_format), NULL) ZEND_NAMED_FE(modify, ZEND_FN(date_modify), NULL) ZEND_NAMED_FE(getTimezone, ZEND_FN(date_timezone_get), NULL) @@ -96,20 +211,21 @@ zend_function_entry date_funcs_date[] = { }; zend_function_entry date_funcs_timezone[] = { + PHP_ME(DateTimeZone, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) ZEND_NAMED_FE(getName, ZEND_FN(timezone_name_get), NULL) ZEND_NAMED_FE(getOffset, ZEND_FN(timezone_offset_get), NULL) - ZEND_NAMED_FE(getTransistions, ZEND_FN(timezone_transistions_get), NULL) - ZEND_MALIAS(timezone, listAbbreviations, abbreviations_list, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - ZEND_MALIAS(timezone, listIdentifiers, identifiers_list, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_NAMED_FE(getTransitions, ZEND_FN(timezone_transitions_get), NULL) + ZEND_ME_MAPPING(listAbbreviations, timezone_abbreviations_list, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME_MAPPING(listIdentifiers, timezone_identifiers_list, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} }; static void date_register_classes(TSRMLS_D); -#endif -static char* guess_timezone(timelib_tzdb *tzdb TSRMLS_DC); +static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC); /* }}} */ ZEND_DECLARE_MODULE_GLOBALS(date) +static PHP_GINIT_FUNCTION(date); /* True global */ timelib_tzdb *php_date_global_timezone_db; @@ -134,7 +250,6 @@ PHP_INI_BEGIN() PHP_INI_END() /* }}} */ -#ifdef EXPERIMENTAL_DATE_SUPPORT zend_class_entry *date_ce_date, *date_ce_timezone; static zend_object_handlers date_object_handlers_date; @@ -171,15 +286,30 @@ struct _php_timezone_obj { } \ obj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); \ +#define DATE_CHECK_INITIALIZED(member, class_name) \ + if (!(member)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The " #class_name " object has not been correctly initialized by its constructor"); \ + RETURN_FALSE; \ + } + static void date_object_free_storage_date(void *object TSRMLS_DC); static void date_object_free_storage_timezone(void *object TSRMLS_DC); static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC); static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC); -#endif +static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC); +static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC); + +/* This is need to ensure that session extension request shutdown occurs 1st, because it uses the date extension */ +static zend_module_dep date_deps[] = { + ZEND_MOD_OPTIONAL("session") + {NULL, NULL, NULL} +}; /* {{{ Module struct */ zend_module_entry date_module_entry = { - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER_EX, + NULL, + date_deps, "date", /* extension name */ date_functions, /* function list */ PHP_MINIT(date), /* process startup */ @@ -188,13 +318,17 @@ zend_module_entry date_module_entry = { PHP_RSHUTDOWN(date), /* request shutdown */ PHP_MINFO(date), /* extension info */ PHP_VERSION, /* extension version */ - STANDARD_MODULE_PROPERTIES + PHP_MODULE_GLOBALS(date), /* globals descriptor */ + PHP_GINIT(date), /* globals ctor */ + NULL, /* globals dtor */ + NULL, /* post deactivate */ + STANDARD_MODULE_PROPERTIES_EX }; /* }}} */ -/* {{{ php_date_init_globals */ -static void php_date_init_globals(zend_date_globals *date_globals) +/* {{{ PHP_GINIT_FUNCTION */ +static PHP_GINIT_FUNCTION(date) { date_globals->default_timezone = NULL; date_globals->timezone = NULL; @@ -237,11 +371,87 @@ PHP_RSHUTDOWN_FUNCTION(date) #define DATE_TIMEZONEDB php_date_global_timezone_db ? php_date_global_timezone_db : timelib_builtin_db() +/* + * RFC822, Section 5.1: http://www.ietf.org/rfc/rfc822.txt + * date-time = [ day "," ] date time ; dd mm yy hh:mm:ss zzz + * day = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" + * date = 1*2DIGIT month 2DIGIT ; day month year e.g. 20 Jun 82 + * month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" + * time = hour zone ; ANSI and Military + * hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT] ; 00:00:00 - 23:59:59 + * zone = "UT" / "GMT" / "EST" / "EDT" / "CST" / "CDT" / "MST" / "MDT" / "PST" / "PDT" / 1ALPHA / ( ("+" / "-") 4DIGIT ) + */ +#define DATE_FORMAT_RFC822 "D, d M y H:i:s O" + +/* + * RFC850, Section 2.1.4: http://www.ietf.org/rfc/rfc850.txt + * Format must be acceptable both to the ARPANET and to the getdate routine. + * One format that is acceptable to both is Weekday, DD-Mon-YY HH:MM:SS TIMEZONE + * TIMEZONE can be any timezone name (3 or more letters) + */ +#define DATE_FORMAT_RFC850 "l, d-M-y H:i:s T" + +/* + * RFC1036, Section 2.1.2: http://www.ietf.org/rfc/rfc1036.txt + * Its format must be acceptable both in RFC-822 and to the getdate(3) + * Wdy, DD Mon YY HH:MM:SS TIMEZONE + * There is no hope of having a complete list of timezones. Universal + * Time (GMT), the North American timezones (PST, PDT, MST, MDT, CST, + * CDT, EST, EDT) and the +/-hhmm offset specifed in RFC-822 should be supported. + */ +#define DATE_FORMAT_RFC1036 "D, d M y H:i:s O" + +/* + * RFC1123, Section 5.2.14: http://www.ietf.org/rfc/rfc1123.txt + * RFC-822 Date and Time Specification: RFC-822 Section 5 + * The syntax for the date is hereby changed to: date = 1*2DIGIT month 2*4DIGIT + */ +#define DATE_FORMAT_RFC1123 "D, d M Y H:i:s O" + +/* + * RFC2822, Section 3.3: http://www.ietf.org/rfc/rfc2822.txt + * FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space + * CFWS = *([FWS] comment) (([FWS] comment) / FWS) + * + * date-time = [ day-of-week "," ] date FWS time [CFWS] + * day-of-week = ([FWS] day-name) + * day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" + * date = day month year + * year = 4*DIGIT + * month = (FWS month-name FWS) + * month-name = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" + * day = ([FWS] 1*2DIGIT) + * time = time-of-day FWS zone + * time-of-day = hour ":" minute [ ":" second ] + * hour = 2DIGIT + * minute = 2DIGIT + * second = 2DIGIT + * zone = (( "+" / "-" ) 4DIGIT) + */ +#define DATE_FORMAT_RFC2822 "D, d M Y H:i:s O" +/* + * RFC3339, Section 5.6: http://www.ietf.org/rfc/rfc3339.txt + * date-fullyear = 4DIGIT + * date-month = 2DIGIT ; 01-12 + * date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year + * + * time-hour = 2DIGIT ; 00-23 + * time-minute = 2DIGIT ; 00-59 + * time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second rules + * + * time-secfrac = "." 1*DIGIT + * time-numoffset = ("+" / "-") time-hour ":" time-minute + * time-offset = "Z" / time-numoffset + * + * partial-time = time-hour ":" time-minute ":" time-second [time-secfrac] + * full-date = date-fullyear "-" date-month "-" date-mday + * full-time = partial-time time-offset + * + * date-time = full-date "T" full-time + */ #define DATE_FORMAT_RFC3339 "Y-m-d\\TH:i:sP" + #define DATE_FORMAT_ISO8601 "Y-m-d\\TH:i:sO" -#define DATE_FORMAT_RFC1036 "l, d-M-y H:i:s T" -#define DATE_FORMAT_RFC1123 "D, d M Y H:i:s T" -#define DATE_FORMAT_RFC2822 "D, d M Y H:i:s O" #define DATE_TZ_ERRMSG \ "It is not safe to rely on the system's timezone settings. Please use " \ @@ -258,20 +468,35 @@ PHP_RSHUTDOWN_FUNCTION(date) /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(date) { - ZEND_INIT_MODULE_GLOBALS(date, php_date_init_globals, NULL); REGISTER_INI_ENTRIES(); -#ifdef EXPERIMENTAL_DATE_SUPPORT date_register_classes(TSRMLS_C); -#endif +/* + * RFC4287, Section 3.3: http://www.ietf.org/rfc/rfc4287.txt + * A Date construct is an element whose content MUST conform to the + * "date-time" production in [RFC3339]. In addition, an uppercase "T" + * character MUST be used to separate date and time, and an uppercase + * "Z" character MUST be present in the absence of a numeric time zone offset. + */ REGISTER_STRING_CONSTANT("DATE_ATOM", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("DATE_COOKIE", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT); +/* + * Preliminary specification: http://wp.netscape.com/newsref/std/cookie_spec.html + * "This is based on RFC 822, RFC 850, RFC 1036, and RFC 1123, + * with the variations that the only legal time zone is GMT + * and the separators between the elements of the date must be dashes." + */ + REGISTER_STRING_CONSTANT("DATE_COOKIE", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_ISO8601", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("DATE_RFC822", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("DATE_RFC850", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("DATE_RFC822", DATE_FORMAT_RFC822, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("DATE_RFC850", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC1036", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT); +/* + * RSS 2.0 Specification: http://blogs.law.harvard.edu/tech/rss + * "All date-times in RSS conform to the Date and Time Specification of RFC 822, + * with the exception that the year may be expressed with two characters or four characters (four preferred)" + */ REGISTER_STRING_CONSTANT("DATE_RSS", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_W3C", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT); @@ -298,7 +523,7 @@ PHP_MSHUTDOWN_FUNCTION(date) /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(date) { - timelib_tzdb *tzdb = DATE_TIMEZONEDB; + const timelib_tzdb *tzdb = DATE_TIMEZONEDB; php_info_print_table_start(); php_info_print_table_row(2, "date/time support", "enabled"); @@ -312,7 +537,7 @@ PHP_MINFO_FUNCTION(date) /* }}} */ /* {{{ Timezone Cache functions */ -static timelib_tzinfo *php_date_parse_tzfile(char *formal_tzname, timelib_tzdb *tzdb TSRMLS_DC) +static timelib_tzinfo *php_date_parse_tzfile(char *formal_tzname, const timelib_tzdb *tzdb TSRMLS_DC) { timelib_tzinfo *tzi, **ptzi; @@ -329,7 +554,7 @@ static timelib_tzinfo *php_date_parse_tzfile(char *formal_tzname, timelib_tzdb * /* }}} */ /* {{{ Helper functions */ -static char* guess_timezone(timelib_tzdb *tzdb TSRMLS_DC) +static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC) { char *env; @@ -455,13 +680,33 @@ static char *english_suffix(timelib_sll number) } /* }}} */ +/* {{{ day of week helpers */ +char *php_date_full_day_name(timelib_sll y, timelib_sll m, timelib_sll d) +{ + timelib_sll day_of_week = timelib_day_of_week(y, m, d); + if (day_of_week < 0) { + return "Unknown"; + } + return day_full_names[day_of_week]; +} + +char *php_date_short_day_name(timelib_sll y, timelib_sll m, timelib_sll d) +{ + timelib_sll day_of_week = timelib_day_of_week(y, m, d); + if (day_of_week < 0) { + return "Unknown"; + } + return day_short_names[day_of_week]; +} +/* }}} */ + /* {{{ date_format - (gm)date helper */ static char *date_format(char *format, int format_len, timelib_time *t, int localtime) { smart_str string = {0}; int i; char buffer[33]; - timelib_time_offset *offset; + timelib_time_offset *offset = NULL; timelib_sll isoweek, isoyear; int rfc_colon = 0; @@ -497,9 +742,9 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca switch (format[i]) { /* day */ case 'd': snprintf(buffer, 32, "%02d", (int) t->d); break; - case 'D': snprintf(buffer, 32, "%s", day_short_names[timelib_day_of_week(t->y, t->m, t->d)]); break; + case 'D': snprintf(buffer, 32, "%s", php_date_short_day_name(t->y, t->m, t->d)); break; case 'j': snprintf(buffer, 32, "%d", (int) t->d); break; - case 'l': snprintf(buffer, 32, "%s", day_full_names[timelib_day_of_week(t->y, t->m, t->d)]); break; + case 'l': snprintf(buffer, 32, "%s", php_date_full_day_name(t->y, t->m, t->d)); break; case 'S': snprintf(buffer, 32, "%s", english_suffix(t->d)); break; case 'w': snprintf(buffer, 32, "%d", (int) timelib_day_of_week(t->y, t->m, t->d)); break; case 'N': snprintf(buffer, 32, "%d", (int) timelib_iso_day_of_week(t->y, t->m, t->d)); break; @@ -530,7 +775,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca retval += 1000; } retval = retval % 1000; - snprintf(buffer, 32, "%03d", retval); break; + snprintf(buffer, 32, "%03d", retval); break; } case 'g': snprintf(buffer, 32, "%d", (t->h % 12) ? (int) t->h % 12 : 12); break; @@ -564,7 +809,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca ); break; case 'r': snprintf(buffer, 32, "%3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d", - day_short_names[timelib_day_of_week(t->y, t->m, t->d)], + php_date_short_day_name(t->y, t->m, t->d), (int) t->d, mon_short_names[t->m - 1], (int) t->y, (int) t->h, (int) t->i, (int) t->s, localtime ? ((offset->offset < 0) ? '-' : '+') : '+', @@ -643,7 +888,7 @@ 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_time_offset *offset = NULL; timelib_sll isoweek, isoyear; t = timelib_time_ctor(); @@ -783,7 +1028,7 @@ PHP_FUNCTION(idate) /* {{{ php_date_set_tzdb - NOT THREADSAFE */ PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb) { - timelib_tzdb *builtin = timelib_builtin_db(); + const timelib_tzdb *builtin = timelib_builtin_db(); if (php_version_compare(tzdb->version, builtin->version) > 0) { php_date_global_timezone_db = tzdb; @@ -848,6 +1093,11 @@ PHP_FUNCTION(strtotime) RETURN_FALSE; } + if (!time_len) { + timelib_time_dtor(now); + RETURN_FALSE; + } + t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB); error1 = error->error_count; timelib_error_container_dtor(error); @@ -863,7 +1113,7 @@ PHP_FUNCTION(strtotime) timelib_tzinfo_dtor(t->tz_info); } - timelib_time_dtor(now); + timelib_time_dtor(now); timelib_time_dtor(t); if (error1 || error2) { @@ -880,7 +1130,7 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) { long hou, min, sec, mon, day, yea, dst = -1; timelib_time *now; - timelib_tzinfo *tzi; + timelib_tzinfo *tzi = NULL; long ts, adjust_seconds = 0; int error; @@ -967,7 +1217,7 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) } /* }}} */ -/* {{{ proto int mktime(int hour, int min, int sec, int mon, int day, int year) +/* {{{ proto int mktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]]) Get UNIX timestamp for a date */ PHP_FUNCTION(mktime) { @@ -975,7 +1225,7 @@ PHP_FUNCTION(mktime) } /* }}} */ -/* {{{ proto int gmmktime(int hour, int min, int sec, int mon, int day, int year) +/* {{{ 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) { @@ -1013,7 +1263,7 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt) size_t buf_len = 64, real_len; timelib_time *ts; timelib_tzinfo *tzi; - timelib_time_offset *offset; + timelib_time_offset *offset = NULL; timestamp = (long) time(NULL); @@ -1116,7 +1366,7 @@ PHP_FUNCTION(time) PHP_FUNCTION(localtime) { long timestamp = (long)time(NULL); - int associative = 0; + zend_bool associative = 0; timelib_tzinfo *tzi; timelib_time *ts; @@ -1186,7 +1436,7 @@ PHP_FUNCTION(getdate) add_assoc_long(return_value, "mon", ts->m); add_assoc_long(return_value, "year", ts->y); add_assoc_long(return_value, "yday", timelib_day_of_year(ts->y, ts->m, ts->d)); - add_assoc_string(return_value, "weekday", day_full_names[timelib_day_of_week(ts->y, ts->m, ts->d)], 1); + add_assoc_string(return_value, "weekday", php_date_full_day_name(ts->y, ts->m, ts->d), 1); add_assoc_string(return_value, "month", mon_full_names[ts->m - 1], 1); add_index_long(return_value, 0, timestamp); @@ -1194,41 +1444,40 @@ PHP_FUNCTION(getdate) } /* }}} */ -#ifdef EXPERIMENTAL_DATE_SUPPORT static void date_register_classes(TSRMLS_D) { zend_class_entry ce_date, ce_timezone; - INIT_CLASS_ENTRY(ce_date, "date", date_funcs_date); + INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date); ce_date.create_object = date_object_new_date; date_ce_date = zend_register_internal_class_ex(&ce_date, NULL, NULL TSRMLS_CC); memcpy(&date_object_handlers_date, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - date_object_handlers_date.clone_obj = NULL; + date_object_handlers_date.clone_obj = date_object_clone_date; #define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \ zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC); REGISTER_DATE_CLASS_CONST_STRING("ATOM", DATE_FORMAT_RFC3339); - REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_RFC1123); + REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_RFC850); REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601); - REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC1123); - REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC1036); + REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC822); + REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC850); REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036); REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123); REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822); REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339); REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123); - REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_ISO8601); + REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339); - INIT_CLASS_ENTRY(ce_timezone, "timezone", date_funcs_timezone); + INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", date_funcs_timezone); ce_timezone.create_object = date_object_new_timezone; date_ce_timezone = zend_register_internal_class_ex(&ce_timezone, NULL, NULL TSRMLS_CC); memcpy(&date_object_handlers_timezone, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - date_object_handlers_timezone.clone_obj = NULL; + date_object_handlers_timezone.clone_obj = date_object_clone_timezone; } -static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC) +static inline zend_object_value date_object_new_date_ex(zend_class_entry *class_type, php_date_obj **ptr TSRMLS_DC) { php_date_obj *intern; zend_object_value retval; @@ -1236,6 +1485,9 @@ static zend_object_value date_object_new_date(zend_class_entry *class_type TSRML intern = emalloc(sizeof(php_date_obj)); memset(intern, 0, sizeof(php_date_obj)); + if (ptr) { + *ptr = intern; + } zend_object_std_init(&intern->std, class_type TSRMLS_CC); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); @@ -1246,7 +1498,33 @@ static zend_object_value date_object_new_date(zend_class_entry *class_type TSRML return retval; } -static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC) +static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC) +{ + return date_object_new_date_ex(class_type, NULL TSRMLS_CC); +} + +static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC) +{ + php_date_obj *new_obj = NULL; + php_date_obj *old_obj = (php_date_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC); + zend_object_value new_ov = date_object_new_date_ex(old_obj->std.ce, &new_obj TSRMLS_CC); + + zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC); + + /* this should probably moved to a new `timelib_time *timelime_time_clone(timelib_time *)` */ + new_obj->time = timelib_time_ctor(); + *new_obj->time = *old_obj->time; + if (old_obj->time->tz_abbr) { + new_obj->time->tz_abbr = strdup(old_obj->time->tz_abbr); + } + if (old_obj->time->tz_info) { + new_obj->time->tz_info = timelib_tzinfo_clone(old_obj->time->tz_info); + } + + return new_ov; +} + +static inline zend_object_value date_object_new_timezone_ex(zend_class_entry *class_type, php_timezone_obj **ptr TSRMLS_DC) { php_timezone_obj *intern; zend_object_value retval; @@ -1254,6 +1532,9 @@ static zend_object_value date_object_new_timezone(zend_class_entry *class_type T intern = emalloc(sizeof(php_timezone_obj)); memset(intern, 0, sizeof(php_timezone_obj)); + if (ptr) { + *ptr = intern; + } zend_object_std_init(&intern->std, class_type TSRMLS_CC); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); @@ -1264,6 +1545,23 @@ static zend_object_value date_object_new_timezone(zend_class_entry *class_type T return retval; } +static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC) +{ + return date_object_new_timezone_ex(class_type, NULL TSRMLS_CC); +} + +static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC) +{ + php_timezone_obj *new_obj = NULL; + php_timezone_obj *old_obj = (php_timezone_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC); + zend_object_value new_ov = date_object_new_timezone_ex(old_obj->std.ce, &new_obj TSRMLS_CC); + + zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC); + new_obj->tz = old_obj->tz; + + return new_ov; +} + static void date_object_free_storage_date(void *object TSRMLS_DC) { php_date_obj *intern = (php_date_obj *)object; @@ -1288,7 +1586,7 @@ static void date_object_free_storage_timezone(void *object TSRMLS_DC) } /* Advanced Interface */ -static zval * date_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC) +static zval * date_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC) { if (!object) { ALLOC_ZVAL(object); @@ -1297,27 +1595,33 @@ static zval * date_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC) Z_TYPE_P(object) = IS_OBJECT; object_init_ex(object, pce); object->refcount = 1; - object->is_ref = 1; + object->is_ref = 0; return object; } -PHP_FUNCTION(date_create) +static void date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int time_str_len, zval *timezone_object TSRMLS_DC) { - php_date_obj *dateobj; - zval *timezone_object = NULL; timelib_time *now; timelib_tzinfo *tzi; - char *time_str; - int time_str_len = 0, free_tzi = 0;; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO", &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) { - RETURN_FALSE; + timelib_error_container *err = NULL; + int free_tzi = 0; + + if (dateobj->time) { + if (dateobj->time->tz_info) { + timelib_tzinfo_dtor(dateobj->time->tz_info); + } + timelib_time_dtor(dateobj->time); + } + dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, &err, DATE_TIMEZONEDB); + if (err) { + if (err->error_count) { + /* spit out the first library error message, at least */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", time_str, + err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message); + } + timelib_error_container_dtor(err); } - date_instanciate(date_ce_date, return_value TSRMLS_CC); - dateobj = (php_date_obj *) zend_object_store_get_object(return_value TSRMLS_CC); - dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, NULL, DATE_TIMEZONEDB); - if (timezone_object) { php_timezone_obj *tzobj; @@ -1348,6 +1652,41 @@ PHP_FUNCTION(date_create) timelib_time_dtor(now); } +/* {{{ proto DateTime date_create([string time[, DateTimeZone object]]) +*/ +PHP_FUNCTION(date_create) +{ + zval *timezone_object = NULL; + char *time_str = NULL; + int time_str_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO", &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) { + RETURN_FALSE; + } + + date_instantiate(date_ce_date, return_value TSRMLS_CC); + date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, timezone_object TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto DateTime::__construct([string time[, DateTimeZone object]]) +*/ +PHP_METHOD(DateTime, __construct) +{ + zval *timezone_object = NULL; + char *time_str = NULL; + int time_str_len = 0; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) { + php_set_error_handling(EH_THROW, NULL TSRMLS_CC); + date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, timezone_object TSRMLS_CC); + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto array date_parse(string date) +*/ PHP_FUNCTION(date_parse) { char *date; @@ -1442,7 +1781,10 @@ PHP_FUNCTION(date_parse) } timelib_time_dtor(parsed_time); } +/* }}} */ +/* {{{ proto string date_format(DateTime object, string format) +*/ PHP_FUNCTION(date_format) { zval *object; @@ -1454,9 +1796,13 @@ PHP_FUNCTION(date_format) RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); RETURN_STRING(date_format(format, format_len, dateobj->time, dateobj->time->is_localtime), 0); } +/* }}} */ +/* {{{ proto void date_modify(DateTime object, string modify) +*/ PHP_FUNCTION(date_modify) { zval *object; @@ -1469,6 +1815,7 @@ PHP_FUNCTION(date_modify) RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); tmp_time = timelib_strtotime(modify, modify_len, NULL, DATE_TIMEZONEDB); dateobj->time->relative.y = tmp_time->relative.y; @@ -1486,7 +1833,10 @@ PHP_FUNCTION(date_modify) timelib_update_ts(dateobj->time, NULL); timelib_update_from_sse(dateobj->time); } +/* }}} */ +/* {{{ proto DateTimeZone date_timezone_get(DateTime object) +*/ PHP_FUNCTION(date_timezone_get) { zval *object; @@ -1497,15 +1847,19 @@ PHP_FUNCTION(date_timezone_get) RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); if (dateobj->time->is_localtime && dateobj->time->tz_info) { - date_instanciate(date_ce_timezone, return_value TSRMLS_CC); + date_instantiate(date_ce_timezone, return_value TSRMLS_CC); tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value TSRMLS_CC); tzobj->tz = timelib_tzinfo_clone(dateobj->time->tz_info); } else { RETURN_FALSE; } } +/* }}} */ +/* {{{ proto void date_timezone_set(DateTime object, DateTimeZone object) +*/ PHP_FUNCTION(date_timezone_set) { zval *object; @@ -1513,10 +1867,11 @@ PHP_FUNCTION(date_timezone_set) php_date_obj *dateobj; php_timezone_obj *tzobj; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O", &object, date_ce_date, &timezone_object, date_ce_timezone) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &timezone_object, date_ce_timezone) == FAILURE) { RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC); if (dateobj->time->tz_info) { timelib_tzinfo_dtor(dateobj->time->tz_info); @@ -1524,7 +1879,10 @@ PHP_FUNCTION(date_timezone_set) timelib_set_timezone(dateobj->time, timelib_tzinfo_clone(tzobj->tz)); timelib_unixtime2local(dateobj->time, dateobj->time->sse); } +/* }}} */ +/* {{{ proto long date_offset_get(DateTime object) +*/ PHP_FUNCTION(date_offset_get) { zval *object; @@ -1535,6 +1893,7 @@ PHP_FUNCTION(date_offset_get) RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); if (dateobj->time->is_localtime && dateobj->time->tz_info) { offset = timelib_get_time_zone_info(dateobj->time->sse, dateobj->time->tz_info); RETVAL_LONG(offset->offset); @@ -1544,7 +1903,10 @@ PHP_FUNCTION(date_offset_get) RETURN_LONG(0); } } +/* }}} */ +/* {{{ proto void date_time_set(DateTime object, long hour, long minute[, long second]) +*/ PHP_FUNCTION(date_time_set) { zval *object; @@ -1555,12 +1917,16 @@ PHP_FUNCTION(date_time_set) RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); dateobj->time->h = h; dateobj->time->i = i; dateobj->time->s = s; timelib_update_ts(dateobj->time, NULL); } +/* }}} */ +/* {{{ proto void date_date_set(DateTime object, long year, long month, long day) +*/ PHP_FUNCTION(date_date_set) { zval *object; @@ -1571,12 +1937,16 @@ PHP_FUNCTION(date_date_set) RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); dateobj->time->y = y; dateobj->time->m = m; dateobj->time->d = d; timelib_update_ts(dateobj->time, NULL); } +/* }}} */ +/* {{{ proto void date_isodate_set(DateTime object, long year, long week[, long day]) +*/ PHP_FUNCTION(date_isodate_set) { zval *object; @@ -1587,6 +1957,7 @@ PHP_FUNCTION(date_isodate_set) RETURN_FALSE; } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); dateobj->time->y = y; dateobj->time->m = 1; dateobj->time->d = 1; @@ -1595,11 +1966,32 @@ PHP_FUNCTION(date_isodate_set) timelib_update_ts(dateobj->time, NULL); } +/* }}} */ +static int timezone_initialize(timelib_tzinfo **tzi, /*const*/ char *tz TSRMLS_DC) +{ + char *tzid; + + *tzi = NULL; + + if ((tzid = timelib_timezone_id_from_abbr(tz, -1, 0))) { + *tzi = php_date_parse_tzfile(tzid, DATE_TIMEZONEDB TSRMLS_CC); + } else { + *tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC); + } + + if (*tzi) { + return SUCCESS; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad timezone (%s)", tz); + return FAILURE; + } +} +/* {{{ proto DateTimeZone timezone_open(string timezone) +*/ PHP_FUNCTION(timezone_open) { - php_timezone_obj *tzobj; char *tz; int tz_len; timelib_tzinfo *tzi = NULL; @@ -1607,29 +1999,33 @@ PHP_FUNCTION(timezone_open) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len) == FAILURE) { RETURN_FALSE; } - /* Try finding the tz information as "Timezone Abbreviation" */ - if (!tzi) { - char *tzid; - - tzid = timelib_timezone_id_from_abbr(tz, -1, 0); - if (tzid) { - tzi = php_date_parse_tzfile(tzid, DATE_TIMEZONEDB TSRMLS_CC); - } - } - /* Try finding the tz information as "Timezone Identifier" */ - if (!tzi) { - tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC); - } - /* If we find it we instantiate the object otherwise, well, we don't and return false */ - if (tzi) { - date_instanciate(date_ce_timezone, return_value TSRMLS_CC); - tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value TSRMLS_CC); - tzobj->tz = tzi; - } else { + if (SUCCESS != timezone_initialize(&tzi, tz TSRMLS_CC)) { RETURN_FALSE; } + ((php_timezone_obj *) zend_object_store_get_object(date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC))->tz = tzi; } +/* }}} */ + +/* {{{ proto DateTimeZone::__construct(string timezone) +*/ +PHP_METHOD(DateTimeZone, __construct) +{ + char *tz; + int tz_len; + timelib_tzinfo *tzi = NULL; + + php_set_error_handling(EH_THROW, NULL TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) { + if (SUCCESS == timezone_initialize(&tzi, tz TSRMLS_CC)) { + ((php_timezone_obj *) zend_object_store_get_object(getThis() TSRMLS_CC))->tz = tzi; + } + } + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); +} +/* }}} */ +/* {{{ proto string timezone_name_get(DateTimeZone object) +*/ PHP_FUNCTION(timezone_name_get) { zval *object; @@ -1639,10 +2035,14 @@ PHP_FUNCTION(timezone_name_get) RETURN_FALSE; } tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(tzobj->tz, DateTimeZone); RETURN_STRING(tzobj->tz->name, 1); } +/* }}} */ +/* {{{ proto string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]]) +*/ PHP_FUNCTION(timezone_name_from_abbr) { char *abbr; @@ -1662,7 +2062,10 @@ PHP_FUNCTION(timezone_name_from_abbr) RETURN_FALSE; } } +/* }}} */ +/* {{{ proto long timezone_offset_get(DateTimeZone object, DateTime object) +*/ PHP_FUNCTION(timezone_offset_get) { zval *object, *dateobject; @@ -1674,14 +2077,19 @@ PHP_FUNCTION(timezone_offset_get) RETURN_FALSE; } tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(tzobj->tz, DateTimeZone); dateobj = (php_date_obj *) zend_object_store_get_object(dateobject TSRMLS_CC); + DATE_CHECK_INITIALIZED(dateobj->time, DateTime); offset = timelib_get_time_zone_info(dateobj->time->sse, tzobj->tz); RETVAL_LONG(offset->offset); timelib_time_offset_dtor(offset); } +/* }}} */ -PHP_FUNCTION(timezone_transistions_get) +/* {{{ proto array timezone_transitions_get(DateTimeZone object) +*/ +PHP_FUNCTION(timezone_transitions_get) { zval *object, *element; php_timezone_obj *tzobj; @@ -1691,6 +2099,7 @@ PHP_FUNCTION(timezone_transistions_get) RETURN_FALSE; } tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(tzobj->tz, DateTimeZone); array_init(return_value); for (i = 0; i < tzobj->tz->timecnt; ++i) { @@ -1705,12 +2114,15 @@ PHP_FUNCTION(timezone_transistions_get) add_next_index_zval(return_value, element); } } +/* }}} */ +/* {{{ proto array timezone_identifiers_list() +*/ PHP_FUNCTION(timezone_identifiers_list) { - timelib_tzdb *tzdb; - timelib_tzdb_index_entry *table; - int i, item_count; + const timelib_tzdb *tzdb; + const timelib_tzdb_index_entry *table; + int i, item_count; tzdb = DATE_TIMEZONEDB; item_count = tzdb->index_size; @@ -1722,11 +2134,14 @@ PHP_FUNCTION(timezone_identifiers_list) add_next_index_string(return_value, table[i].id, 1); }; } +/* }}} */ +/* proto {{{ array timezone_abbreviations_list() +*/ PHP_FUNCTION(timezone_abbreviations_list) { - timelib_tz_lookup_table *table, *entry; - zval *element, **abbr_array_pp, *abbr_array; + const timelib_tz_lookup_table *table, *entry; + zval *element, **abbr_array_pp, *abbr_array; table = timelib_timezone_abbreviations_list(); array_init(return_value); @@ -1754,8 +2169,7 @@ PHP_FUNCTION(timezone_abbreviations_list) entry++; } while (entry->name); } -#endif - +/* }}} */ /* {{{ proto bool date_default_timezone_set(string timezone_identifier) Sets the default timezone used by all date/time functions in a script */ |