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 | |
| 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')
| -rw-r--r-- | ext/intl/timezone/timezone_class.cpp | 77 | ||||
| -rw-r--r-- | ext/intl/timezone/timezone_class.h | 1 | ||||
| -rw-r--r-- | ext/intl/timezone/timezone_methods.cpp | 57 | ||||
| -rw-r--r-- | ext/intl/timezone/timezone_methods.h | 4 |
4 files changed, 137 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 diff --git a/ext/intl/timezone/timezone_class.h b/ext/intl/timezone/timezone_class.h index d5fabb9280..0d3c0edde4 100644 --- a/ext/intl/timezone/timezone_class.h +++ b/ext/intl/timezone/timezone_class.h @@ -60,6 +60,7 @@ typedef struct { } TimeZone *timezone_convert_datetimezone(int type, void *object, int is_datetime, intl_error *outside_error, const char *func TSRMLS_DC); +zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, const char *func TSRMLS_DC); TimeZone *timezone_process_timezone_argument(zval **zv_timezone, intl_error *error, const char *func TSRMLS_DC); void timezone_object_construct(const TimeZone *zone, zval *object, int owned TSRMLS_DC); diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp index eaa6b46e39..e596cc5174 100644 --- a/ext/intl/timezone/timezone_methods.cpp +++ b/ext/intl/timezone/timezone_methods.cpp @@ -28,6 +28,9 @@ extern "C" { #include "intl_convert.h" #include "../locale/locale.h" #include <zend_exceptions.h> +/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */ +#define _MSC_STDINT_H_ 1 +#include <ext/date/php_date.h> } #include "common/common_enum.h" @@ -57,6 +60,37 @@ U_CFUNC PHP_FUNCTION(intltz_create_time_zone) timezone_object_construct(tz, return_value, 1 TSRMLS_CC); } +U_CFUNC PHP_FUNCTION(intltz_from_date_time_zone) +{ + zval *zv_timezone; + TimeZone *tz; + php_timezone_obj *tzobj; + intl_error_reset(NULL TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", + &zv_timezone, php_date_get_timezone_ce()) == FAILURE) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "intltz_from_date_time_zone: bad arguments", 0 TSRMLS_CC); + RETURN_NULL(); + } + + tzobj = (php_timezone_obj *)zend_objects_get_address(zv_timezone TSRMLS_CC); + if (!tzobj->initialized) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "intltz_from_date_time_zone: DateTimeZone object is unconstructed", + 0 TSRMLS_CC); + RETURN_NULL(); + } + + tz = timezone_convert_datetimezone(tzobj->type, tzobj, FALSE, NULL, + "intltz_from_date_time_zone" TSRMLS_CC); + if (tz == NULL) { + RETURN_NULL(); + } + + timezone_object_construct(tz, return_value, 1 TSRMLS_CC); +} + U_CFUNC PHP_FUNCTION(intltz_create_default) { intl_error_reset(NULL TSRMLS_CC); @@ -549,6 +583,29 @@ U_CFUNC PHP_FUNCTION(intltz_get_dst_savings) RETURN_LONG((long)to->utimezone->getDSTSavings()); } +U_CFUNC PHP_FUNCTION(intltz_to_date_time_zone) +{ + TIMEZONE_METHOD_INIT_VARS; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), + "O", &object, TimeZone_ce_ptr) == FAILURE) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "intltz_to_date_time_zone: bad arguments", 0 TSRMLS_CC); + RETURN_FALSE; + } + + TIMEZONE_METHOD_FETCH_OBJECT; + + zval *ret = timezone_convert_to_datetimezone(to->utimezone, + &TIMEZONE_ERROR(to), "intltz_to_date_time_zone" TSRMLS_CC); + + if (ret) { + RETURN_ZVAL(ret, 1, 1); + } else { + RETURN_FALSE; + } +} + U_CFUNC PHP_FUNCTION(intltz_get_error_code) { TIMEZONE_METHOD_INIT_VARS diff --git a/ext/intl/timezone/timezone_methods.h b/ext/intl/timezone/timezone_methods.h index 207caa3cb0..824f72a0d2 100644 --- a/ext/intl/timezone/timezone_methods.h +++ b/ext/intl/timezone/timezone_methods.h @@ -21,6 +21,8 @@ PHP_FUNCTION(intltz_create_time_zone); +PHP_FUNCTION(intltz_from_date_time_zone); + PHP_FUNCTION(intltz_create_default); PHP_FUNCTION(intltz_get_id); @@ -55,6 +57,8 @@ PHP_FUNCTION(intltz_get_display_name); PHP_FUNCTION(intltz_get_dst_savings); +PHP_FUNCTION(intltz_to_date_time_zone); + PHP_FUNCTION(intltz_get_error_code); PHP_FUNCTION(intltz_get_error_message); |
