U_CFUNC PHP_FUNCTION(intlcal_create_instance) { zval *zv_timezone = NULL; const char *locale_str = NULL; size_t dummy; TimeZone *timeZone; UErrorCode status = U_ZERO_ERROR; intl_error_reset(NULL TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zs!", &zv_timezone, &locale_str, &dummy) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_create_calendar: bad arguments", 0 TSRMLS_CC); RETURN_NULL(); } timeZone = timezone_process_timezone_argument(zv_timezone, NULL, "intlcal_create_instance" TSRMLS_CC); if (timeZone == NULL) { RETURN_NULL(); } if (!locale_str) { locale_str = intl_locale_get_default(TSRMLS_C); } Calendar *cal = Calendar::createInstance(timeZone, Locale::createFromName(locale_str), status); if (cal == NULL) { delete timeZone; intl_error_set(NULL, status, "Error creating ICU Calendar object", 0 TSRMLS_CC); RETURN_NULL(); } calendar_object_create(return_value, cal TSRMLS_CC); }
U_CFUNC PHP_FUNCTION(intlcal_from_date_time) { zval *zv_arg, zv_tmp, *zv_datetime = NULL, zv_timestamp; php_date_obj *datetime; char *locale_str = NULL; int locale_str_len; TimeZone *timeZone; UErrorCode status = U_ZERO_ERROR; Calendar *cal; intl_error_reset(NULL TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|s!", &zv_arg, &locale_str, &locale_str_len) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_from_date_time: bad arguments", 0 TSRMLS_CC); RETURN_NULL(); } if (!(Z_TYPE_P(zv_arg) == IS_OBJECT && instanceof_function( Z_OBJCE_P(zv_arg), php_date_get_date_ce() TSRMLS_CC))) { object_init_ex(&zv_tmp, php_date_get_date_ce()); zend_call_method_with_1_params(&zv_tmp, NULL, NULL, "__construct", NULL, zv_arg); if (EG(exception)) { zend_object_store_ctor_failed(Z_OBJ(zv_tmp) TSRMLS_CC); goto error; } zv_datetime = &zv_tmp; } else { zv_datetime = zv_arg; } datetime = Z_PHPDATE_P(zv_datetime); if (!datetime->time) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_from_date_time: DateTime object is unconstructed", 0 TSRMLS_CC); goto error; } zend_call_method_with_0_params(zv_datetime, php_date_get_date_ce(), NULL, "gettimestamp", &zv_timestamp); if (Z_TYPE(zv_timestamp) != IS_LONG) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_from_date_time: bad DateTime; call to " "DateTime::getTimestamp() failed", 0 TSRMLS_CC); zval_ptr_dtor(&zv_timestamp); goto error; } if (!datetime->time->is_localtime) { timeZone = TimeZone::getGMT()->clone(); } else { timeZone = timezone_convert_datetimezone(datetime->time->zone_type, datetime, 1, NULL, "intlcal_from_date_time" TSRMLS_CC); if (timeZone == NULL) { goto error; } } if (!locale_str) { locale_str = const_cast<char*>(intl_locale_get_default(TSRMLS_C)); } cal = Calendar::createInstance(timeZone, Locale::createFromName(locale_str), status); if (cal == NULL) { delete timeZone; intl_error_set(NULL, status, "intlcal_from_date_time: " "error creating ICU Calendar object", 0 TSRMLS_CC); goto error; } cal->setTime(((UDate)Z_LVAL(zv_timestamp)) * 1000., status); if (U_FAILURE(status)) { /* time zone was adopted by cal; should not be deleted here */ delete cal; intl_error_set(NULL, status, "intlcal_from_date_time: " "error creating ICU Calendar::setTime()", 0 TSRMLS_CC); goto error; } calendar_object_create(return_value, cal TSRMLS_CC); error: if (zv_datetime && zv_datetime != zv_arg) { zval_ptr_dtor(zv_datetime); } }
/* {{{ */ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { zval *object; const char *locale_str; size_t locale_len = 0; Locale locale; zend_long date_type = 0; zend_long time_type = 0; zval *calendar_zv = NULL; Calendar *calendar = NULL; zend_long calendar_type; bool calendar_owned; zval *timezone_zv = NULL; TimeZone *timezone = NULL; bool explicit_tz; char* pattern_str = NULL; size_t pattern_str_len = 0; UChar* svalue = NULL; /* UTF-16 pattern_str */ int32_t slength = 0; IntlDateFormatter_object* dfo; intl_error_reset(NULL); object = return_value; /* Parse parameters. */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll|zzs", &locale_str, &locale_len, &date_type, &time_type, &timezone_zv, &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: " "unable to parse input parameters", 0); Z_OBJ_P(return_value) = NULL; return; } INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); if (locale_len == 0) { locale_str = intl_locale_get_default(); } locale = Locale::createFromName(locale_str); DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; if (DATE_FORMAT_OBJECT(dfo) != NULL) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: cannot call constructor twice", 0); return; } /* process calendar */ if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create", INTL_DATA_ERROR_P(dfo), calendar, calendar_type, calendar_owned) == FAILURE) { goto error; } /* process timezone */ explicit_tz = timezone_zv != NULL && Z_TYPE_P(timezone_zv) != IS_NULL; if (explicit_tz || calendar_owned ) { //we have an explicit time zone or a non-object calendar timezone = timezone_process_timezone_argument(timezone_zv, INTL_DATA_ERROR_P(dfo), "datefmt_create"); if (timezone == NULL) { goto error; } } /* Convert pattern (if specified) to UTF-16. */ if (pattern_str && pattern_str_len > 0) { intl_convert_utf8_to_utf16(&svalue, &slength, pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { /* object construction -> only set global error */ intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " "error converting pattern to UTF-16", 0); goto error; } } if (pattern_str && pattern_str_len > 0) { DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale_str, NULL, 0, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); } else { DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type, (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); } if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo); if (calendar_owned) { df->adoptCalendar(calendar); calendar_owned = false; } else { df->setCalendar(*calendar); } if (timezone != NULL) { df->adoptTimeZone(timezone); } } else { intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date " "formatter creation failed", 0); goto error; } /* Set the class variables */ dfo->date_type = date_type; dfo->time_type = time_type; dfo->calendar = calendar_type; dfo->requested_locale = estrdup(locale_str); error: if (svalue) { efree(svalue); } if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) { delete timezone; } if (calendar != NULL && calendar_owned) { delete calendar; } if (U_FAILURE(intl_error_get_code(NULL))) { /* free_object handles partially constructed instances fine */ Z_OBJ_P(return_value) = NULL; } }
static void _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAMETERS) { zval *tz_object = NULL; zval args_a[6] = {0}, *args = &args_a[0]; char *locale = NULL; int locale_len; zend_long largs[6]; UErrorCode status = U_ZERO_ERROR; int variant; intl_error_reset(NULL TSRMLS_CC); // parameter number validation / variant determination if (ZEND_NUM_ARGS() > 6 || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlgregcal_create_instance: too many arguments", 0 TSRMLS_CC); Z_OBJ_P(return_value) = NULL; return; } for (variant = ZEND_NUM_ARGS(); variant > 0 && Z_TYPE(args[variant - 1]) == IS_NULL; variant--) {} if (variant == 4) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlgregcal_create_instance: no variant with 4 arguments " "(excluding trailing NULLs)", 0 TSRMLS_CC); Z_OBJ_P(return_value) = NULL; return; } // argument parsing if (variant <= 2) { if (zend_parse_parameters(MIN(ZEND_NUM_ARGS(), 2) TSRMLS_CC, "|z!s!", &tz_object, &locale, &locale_len) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlgregcal_create_instance: bad arguments", 0 TSRMLS_CC); Z_OBJ_P(return_value) = NULL; return; } } if (variant > 2 && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll|lll", &largs[0], &largs[1], &largs[2], &largs[3], &largs[4], &largs[5]) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlgregcal_create_instance: bad arguments", 0 TSRMLS_CC); Z_OBJ_P(return_value) = NULL; return; } // instantion of ICU object GregorianCalendar *gcal = NULL; if (variant <= 2) { // From timezone and locale (0 to 2 arguments) TimeZone *tz = timezone_process_timezone_argument(tz_object, NULL, "intlgregcal_create_instance" TSRMLS_CC); if (tz == NULL) { Z_OBJ_P(return_value) = NULL; return; } if (!locale) { locale = const_cast<char*>(intl_locale_get_default(TSRMLS_C)); } gcal = new GregorianCalendar(tz, Locale::createFromName(locale), status); if (U_FAILURE(status)) { intl_error_set(NULL, status, "intlgregcal_create_instance: error " "creating ICU GregorianCalendar from time zone and locale", 0 TSRMLS_CC); if (gcal) { delete gcal; } delete tz; Z_OBJ_P(return_value) = NULL; return; } } else { // From date/time (3, 5 or 6 arguments) for (int i = 0; i < variant; i++) { if (largs[i] < INT32_MIN || largs[i] > INT32_MAX) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlgregcal_create_instance: at least one of the arguments" " has an absolute value that is too large", 0 TSRMLS_CC); Z_OBJ_P(return_value) = NULL; return; } } if (variant == 3) { gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], status); } else if (variant == 5) { gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], status); } else if (variant == 6) { gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], (int32_t)largs[5], status); } if (U_FAILURE(status)) { intl_error_set(NULL, status, "intlgregcal_create_instance: error " "creating ICU GregorianCalendar from date", 0 TSRMLS_CC); if (gcal) { delete gcal; } Z_OBJ_P(return_value) = NULL; return; } timelib_tzinfo *tzinfo = get_timezone_info(TSRMLS_C); #if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 42 UnicodeString tzstr = UnicodeString::fromUTF8(StringPiece(tzinfo->name)); #else UnicodeString tzstr = UnicodeString(tzinfo->name, strlen(tzinfo->name), US_INV); #endif if (tzstr.isBogus()) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlgregcal_create_instance: could not create UTF-8 string " "from PHP's default timezone name (see date_default_timezone_get())", 0 TSRMLS_CC); delete gcal; Z_OBJ_P(return_value) = NULL; return; } TimeZone *tz = TimeZone::createTimeZone(tzstr); gcal->adoptTimeZone(tz); } Calendar_object *co = Z_INTL_CALENDAR_P(return_value); co->ucal = gcal; }
U_CFUNC PHP_FUNCTION(datefmt_format_object) { zval *object, *format = NULL; const char *locale_str = NULL; size_t locale_len; bool pattern = false; UDate date; TimeZone *timeZone = NULL; UErrorCode status = U_ZERO_ERROR; DateFormat *df = NULL; Calendar *cal = NULL; DateFormat::EStyle dateStyle = DateFormat::kDefault, timeStyle = DateFormat::kDefault; if (zend_parse_parameters(ZEND_NUM_ARGS(), "o|zs!", &object, &format, &locale_str, &locale_len) == FAILURE) { RETURN_FALSE; } if (!locale_str) { locale_str = intl_locale_get_default(); } if (format == NULL || Z_TYPE_P(format) == IS_NULL) { //nothing } else if (Z_TYPE_P(format) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(format); HashPosition pos = {0}; zval *z; if (zend_hash_num_elements(ht) != 2) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format_object: bad format; if array, it must have " "two elements", 0); RETURN_FALSE; } zend_hash_internal_pointer_reset_ex(ht, &pos); z = zend_hash_get_current_data_ex(ht, &pos); if (!valid_format(z)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format_object: bad format; the date format (first " "element of the array) is not valid", 0); RETURN_FALSE; } dateStyle = (DateFormat::EStyle)Z_LVAL_P(z); zend_hash_move_forward_ex(ht, &pos); z = zend_hash_get_current_data_ex(ht, &pos); if (!valid_format(z)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format_object: bad format; the time format (" "second element of the array) is not valid", 0); RETURN_FALSE; } timeStyle = (DateFormat::EStyle)Z_LVAL_P(z); } else if (Z_TYPE_P(format) == IS_LONG) { if (!valid_format(format)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format_object: the date/time format type is invalid", 0); RETURN_FALSE; } dateStyle = timeStyle = (DateFormat::EStyle)Z_LVAL_P(format); } else { convert_to_string_ex(format); if (Z_STRLEN_P(format) == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format_object: the format is empty", 0); RETURN_FALSE; } pattern = true; } //there's no support for relative time in ICU yet timeStyle = (DateFormat::EStyle)(timeStyle & ~DateFormat::kRelative); zend_class_entry *instance_ce = Z_OBJCE_P(object); if (instanceof_function(instance_ce, Calendar_ce_ptr)) { Calendar *obj_cal = calendar_fetch_native_calendar(object); if (obj_cal == NULL) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format_object: bad IntlCalendar instance: " "not initialized properly", 0); RETURN_FALSE; } timeZone = obj_cal->getTimeZone().clone(); date = obj_cal->getTime(status); if (U_FAILURE(status)) { intl_error_set(NULL, status, "datefmt_format_object: error obtaining instant from " "IntlCalendar", 0); RETVAL_FALSE; goto cleanup; } cal = obj_cal->clone(); } else if (instanceof_function(instance_ce, php_date_get_date_ce())) { if (intl_datetime_decompose(object, &date, &timeZone, NULL, "datefmt_format_object") == FAILURE) { RETURN_FALSE; } cal = new GregorianCalendar(Locale::createFromName(locale_str), status); if (U_FAILURE(status)) { intl_error_set(NULL, status, "datefmt_format_object: could not create GregorianCalendar", 0); RETVAL_FALSE; goto cleanup; } } else { intl_error_set(NULL, status, "datefmt_format_object: the passed object " "must be an instance of either IntlCalendar or DateTime", 0); RETURN_FALSE; } if (pattern) { df = new SimpleDateFormat( UnicodeString(Z_STRVAL_P(format), Z_STRLEN_P(format), UnicodeString::kInvariant), Locale::createFromName(locale_str), status); if (U_FAILURE(status)) { intl_error_set(NULL, status, "datefmt_format_object: could not create SimpleDateFormat", 0); RETVAL_FALSE; goto cleanup; } } else { df = DateFormat::createDateTimeInstance(dateStyle, timeStyle, Locale::createFromName(locale_str)); if (df == NULL) { /* according to ICU sources, this should never happen */ intl_error_set(NULL, status, "datefmt_format_object: could not create DateFormat", 0); RETVAL_FALSE; goto cleanup; } } //must be in this order (or have the cal adopt the tz) df->adoptCalendar(cal); cal = NULL; df->adoptTimeZone(timeZone); timeZone = NULL; { char *ret_str; int ret_str_len; UnicodeString result = UnicodeString(); df->format(date, result); if (intl_charFromString(result, &ret_str, &ret_str_len, &status) == FAILURE) { intl_error_set(NULL, status, "datefmt_format_object: error converting result to UTF-8", 0); RETVAL_FALSE; goto cleanup; } RETVAL_STRINGL(ret_str, ret_str_len); //??? efree(ret_str); } cleanup: delete df; delete timeZone; delete cal; }
/* {{{ * common code shared by display_xyz functions to get the value from ICU }}} */ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) { const char* loc_name = NULL; size_t loc_name_len = 0; const char* disp_loc_name = NULL; size_t disp_loc_name_len = 0; int free_loc_name = 0; UChar* disp_name = NULL; int32_t disp_name_len = 0; char* mod_loc_name = NULL; int32_t buflen = 512; UErrorCode status = U_ZERO_ERROR; char* utf8value = NULL; size_t utf8value_len = 0; char* msg = NULL; int grOffset = 0; intl_error_reset( NULL ); if(zend_parse_parameters( ZEND_NUM_ARGS(), "s|s", &loc_name, &loc_name_len , &disp_loc_name ,&disp_loc_name_len ) == FAILURE) { spprintf(&msg , 0, "locale_get_display_%s : unable to parse input params", tag_name ); intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, msg , 1 ); efree(msg); RETURN_FALSE; } if(loc_name_len > ULOC_FULLNAME_CAPACITY) { /* See bug 67397: overlong locale names cause trouble in uloc_getDisplayName */ spprintf(&msg , 0, "locale_get_display_%s : name too long", tag_name ); intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, msg , 1 ); efree(msg); RETURN_FALSE; } if(loc_name_len == 0) { loc_name = intl_locale_get_default(); } if( strcmp(tag_name, DISP_NAME) != 0 ){ /* Handle grandfathered languages */ grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); if( grOffset >= 0 ){ if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ mod_loc_name = getPreferredTag( loc_name ); } else { /* Since Grandfathered, no value, do nothing, retutn NULL */ RETURN_FALSE; } } } /* end of if != LOC_CANONICAL_TAG */ if( mod_loc_name==NULL ){ mod_loc_name = estrdup( loc_name ); } /* Check if disp_loc_name passed , if not use default locale */ if( !disp_loc_name){ disp_loc_name = estrdup(intl_locale_get_default()); free_loc_name = 1; } /* Get the disp_value for the given locale */ do{ disp_name = erealloc( disp_name , buflen * sizeof(UChar) ); disp_name_len = buflen; if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ buflen = uloc_getDisplayLanguage ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); } else if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){ buflen = uloc_getDisplayScript ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); } else if( strcmp(tag_name , LOC_REGION_TAG)==0 ){ buflen = uloc_getDisplayCountry ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); } else if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){ buflen = uloc_getDisplayVariant ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); } else if( strcmp(tag_name , DISP_NAME)==0 ){ buflen = uloc_getDisplayName ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); } /* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */ if( U_FAILURE( status ) ) { if( status == U_BUFFER_OVERFLOW_ERROR ) { status = U_ZERO_ERROR; continue; } spprintf(&msg, 0, "locale_get_display_%s : unable to get locale %s", tag_name , tag_name ); intl_error_set( NULL, status, msg , 1 ); efree(msg); if( disp_name){ efree( disp_name ); } if( mod_loc_name){ efree( mod_loc_name ); } if (free_loc_name) { efree((void *)disp_loc_name); disp_loc_name = NULL; } RETURN_FALSE; } } while( buflen > disp_name_len ); if( mod_loc_name){ efree( mod_loc_name ); } if (free_loc_name) { efree((void *)disp_loc_name); disp_loc_name = NULL; } /* Convert display locale name from UTF-16 to UTF-8. */ intl_convert_utf16_to_utf8( &utf8value, &utf8value_len, disp_name, buflen, &status ); efree( disp_name ); if( U_FAILURE( status ) ) { spprintf(&msg, 0, "locale_get_display_%s :error converting display name for %s to UTF-8", tag_name , tag_name ); intl_error_set( NULL, status, msg , 1 ); efree(msg); RETURN_FALSE; } RETVAL_STRINGL( utf8value, utf8value_len ); //???? efree(utf8value); }
U_CFUNC PHP_FUNCTION(intlcal_from_date_time) { zval **zv_arg, *zv_datetime = NULL; double millis; php_date_obj *datetime; char *locale_str = NULL; int locale_str_len; TimeZone *timeZone; UErrorCode status = U_ZERO_ERROR; Calendar *cal; intl_error_reset(NULL TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|s!", &zv_arg, &locale_str, &locale_str_len) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_from_date_time: bad arguments", 0 TSRMLS_CC); RETURN_NULL(); } if (!(Z_TYPE_PP(zv_arg) == IS_OBJECT && instanceof_function( Z_OBJCE_PP(zv_arg), php_date_get_date_ce() TSRMLS_CC))) { ALLOC_INIT_ZVAL(zv_datetime); object_init_ex(zv_datetime, php_date_get_date_ce()); zend_call_method_with_1_params(&zv_datetime, NULL, NULL, "__construct", NULL, *zv_arg); if (EG(exception)) { zend_object_store_ctor_failed(zv_datetime TSRMLS_CC); goto error; } } else { zv_datetime = *zv_arg; } datetime = (php_date_obj*)zend_object_store_get_object(zv_datetime TSRMLS_CC); if (!datetime->time) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_from_date_time: DateTime object is unconstructed", 0 TSRMLS_CC); goto error; } if (intl_datetime_decompose(zv_datetime, &millis, NULL, NULL, "intlcal_from_date_time" TSRMLS_CC) == FAILURE) { goto error; } if (!datetime->time->is_localtime) { timeZone = TimeZone::getGMT()->clone(); } else { timeZone = timezone_convert_datetimezone(datetime->time->zone_type, datetime, 1, NULL, "intlcal_from_date_time" TSRMLS_CC); if (timeZone == NULL) { goto error; } } if (!locale_str) { locale_str = const_cast<char*>(intl_locale_get_default(TSRMLS_C)); } cal = Calendar::createInstance(timeZone, Locale::createFromName(locale_str), status); if (cal == NULL) { delete timeZone; intl_error_set(NULL, status, "intlcal_from_date_time: " "error creating ICU Calendar object", 0 TSRMLS_CC); goto error; } cal->setTime(millis, status); if (U_FAILURE(status)) { /* time zone was adopted by cal; should not be deleted here */ delete cal; intl_error_set(NULL, status, "intlcal_from_date_time: " "error creating ICU Calendar::setTime()", 0 TSRMLS_CC); goto error; } calendar_object_create(return_value, cal TSRMLS_CC); error: if (zv_datetime != *zv_arg) { zval_ptr_dtor(&zv_datetime); } }