diff options
author | Gustavo André dos Santos Lopes <cataphract@php.net> | 2012-04-30 15:15:09 +0200 |
---|---|---|
committer | Gustavo André dos Santos Lopes <cataphract@php.net> | 2012-05-17 17:23:51 +0200 |
commit | 4cfd9995daf249c02f4d8a23f96288d1b2a2f4c0 (patch) | |
tree | 9a05442b20a264bcb2d3f8157b585c6686d911ab /ext/intl/timezone/timezone_class.cpp | |
parent | 22f4a307481f1667bdc95f7ec7c43538427b73ab (diff) | |
download | php-git-4cfd9995daf249c02f4d8a23f96288d1b2a2f4c0.tar.gz |
Added IntlTimeZone::fromDateTimeZone() and ::toDateTimeZone.
IntlTimeZone::fromDateTimeZone(DateTimeZone $dtz) converts from an
ext/date TimeZone to an IntlTimeZone. The conversion is done by feeding
the time zone name (essentially what would be given by
DateTimeZone::getName()) to ICU's TimeZone::createTimeZone except if it's
an offset time zone. In that case, the offset is read from the ext/date
time zone object structure and an appopriate id (of the form
GMT<+|-><HH:MM>) is given to ICU's TimeZone::createTimeZone. Not all
ext/date time zones are recognized for ICU. For instance, WEST is not.
Note that these kind of abbreviations, as far as I can tell, can only be
created via ext/date DateTime, not directly through DateTimeZone's
constructor.
For IntlTimeZone::toDateTimeZone(), the behavior is symmetrical.
We instantiate a DateTimeZone and then call its constructor if we don't
have an offset time zone, otherwise we mess with its structure. If the
timezone is not valid for ext/date, then we allow the exception of
DateTimeZone constructor to propagate.
Diffstat (limited to 'ext/intl/timezone/timezone_class.cpp')
-rw-r--r-- | ext/intl/timezone/timezone_class.cpp | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp index 7032368737..31893fe491 100644 --- a/ext/intl/timezone/timezone_class.cpp +++ b/ext/intl/timezone/timezone_class.cpp @@ -29,6 +29,7 @@ extern "C" { #include "timezone_class.h" #include "timezone_methods.h" #include <zend_exceptions.h> +#include <zend_interfaces.h> /* avoid redefinition of int8_t, already defined in unicode/pwin32.h */ #define _MSC_STDINT_H_ 1 #include <ext/date/php_date.h> @@ -107,7 +108,7 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, UnicodeString s = UnicodeString(id, id_len, US_INV); timeZone = TimeZone::createTimeZone(s); #if U_ICU_VERSION_MAJOR_NUM >= 49 - if (timeZone == TimeZone::getUnknown()) { + if (*timeZone == TimeZone::getUnknown()) { #else UnicodeString resultingId; timeZone->getID(resultingId); @@ -115,7 +116,7 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, || resultingId == UnicodeString("GMT", -1, US_INV)) { #endif spprintf(&message, 0, "%s: time zone id '%s' " - "extracted from ext/date TimeZone not recognized", func, id); + "extracted from ext/date DateTimeZone not recognized", func, id); intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC); efree(message); @@ -126,6 +127,72 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, } /* }}} */ +/* {{{ timezone_convert_to_datetimezone + * Convert from TimeZone to DateTimeZone object */ +U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, + intl_error *outside_error, + const char *func TSRMLS_DC) +{ + zval *ret = NULL; + UnicodeString id; + char *message = NULL; + php_timezone_obj *tzobj; + + timeZone->getID(id); + if (id.isBogus()) { + spprintf(&message, 0, "%s: could not obtain TimeZone id", func); + intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, + message, 1 TSRMLS_CC); + goto error; + } + + MAKE_STD_ZVAL(ret); + object_init_ex(ret, php_date_get_timezone_ce()); + tzobj = (php_timezone_obj *)zend_objects_get_address(ret TSRMLS_CC); + + if (id.compare(0, 3, UnicodeString("GMT", sizeof("GMT")-1, US_INV)) == 0) { + /* The DateTimeZone constructor doesn't support offset time zones, + * so we must mess with DateTimeZone structure ourselves */ + tzobj->initialized = 1; + tzobj->type = TIMELIB_ZONETYPE_OFFSET; + //convert offset from milliseconds to minutes + tzobj->tzi.utc_offset = -1 * timeZone->getRawOffset() / (60 * 1000); + } else { + /* Call the constructor! */ + zval arg = zval_used_for_init; + Z_TYPE(arg) = IS_STRING; + if (intl_charFromString(id, &Z_STRVAL(arg), &Z_STRLEN(arg), + &INTL_ERROR_CODE(*outside_error)) == FAILURE) { + spprintf(&message, 0, "%s: could not convert id to UTF-8", func); + intl_errors_set(outside_error, INTL_ERROR_CODE(*outside_error), + message, 1 TSRMLS_CC); + goto error; + } + zend_call_method_with_1_params(&ret, NULL, NULL, "__construct", + NULL, &arg); + if (EG(exception)) { + spprintf(&message, 0, + "%s: DateTimeZone constructor threw exception", func); + intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, + message, 1 TSRMLS_CC); + zend_object_store_ctor_failed(ret TSRMLS_CC); + goto error; + } + } + + return ret; + +error: + if (message) { + efree(message); + } + if (ret) { + zval_ptr_dtor(&ret); + } + return NULL; +} +/* }}} */ + /* {{{ timezone_process_timezone_argument * TimeZone argument processor. outside_error may be NULL (for static functions/constructors) */ U_CFUNC TimeZone *timezone_process_timezone_argument(zval **zv_timezone, @@ -400,6 +467,10 @@ ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_idarg, 0, 0, 1) ZEND_ARG_INFO(0, zoneId) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_fromDateTimeZone, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, otherTimeZone, IntlTimeZone, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_createEnumeration, 0, 0, 0) ZEND_ARG_INFO(0, countryOrRawOffset) ZEND_END_ARG_INFO() @@ -451,6 +522,7 @@ ZEND_END_ARG_INFO() */ static zend_function_entry TimeZone_class_functions[] = { PHP_ME_MAPPING(createTimeZone, intltz_create_time_zone, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME_MAPPING(fromDateTimeZone, intltz_from_date_time_zone, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME_MAPPING(createDefault, intltz_create_default, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME_MAPPING(getGMT, intltz_get_gmt, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) #if U_ICU_VERSION_MAJOR_NUM >= 49 @@ -475,6 +547,7 @@ static zend_function_entry TimeZone_class_functions[] = { PHP_ME_MAPPING(hasSameRules, intltz_has_same_rules, ainfo_tz_hasSameRules, ZEND_ACC_PUBLIC) PHP_ME_MAPPING(getDisplayName, intltz_get_display_name, ainfo_tz_getDisplayName, ZEND_ACC_PUBLIC) PHP_ME_MAPPING(getDSTSavings, intltz_get_dst_savings, ainfo_tz_void, ZEND_ACC_PUBLIC) + PHP_ME_MAPPING(toDateTimeZone, intltz_to_date_time_zone, ainfo_tz_void, ZEND_ACC_PUBLIC) PHP_ME_MAPPING(getErrorCode, intltz_get_error_code, ainfo_tz_void, ZEND_ACC_PUBLIC) PHP_ME_MAPPING(getErrorMessage, intltz_get_error_message, ainfo_tz_void, ZEND_ACC_PUBLIC) PHP_FE_END |