php-src/ext/intl/timezone/timezone_class.cpp
Gustavo André dos Santos Lopes eb346ef0f4 DateFormat plays nice with Calendar, TimeZone
The following changes were made:

* The IntlDateFormatter constructor now accepts the usual values
  for its $timezone argument. This includes timezone identifiers,
  IntlTimeZone objects, DateTimeZone objects and NULL. An empty
  string is not accepted. An invalid time zone is no longer accepted
  (it used to use UTC in this case).
* When NULL is passed to IntlDateFormatter, the time zone specified in
  date.timezone is used instead of the ICU default.
* The IntlDateFormatter $calendar argument now accepts also an
  IntlCalendar. In this case, IntlDateFormatter::getCalendar() will
  return false.
* The time zone passed to the IntlDateFormatter is ignored if it is
  NULL and if the calendar passed is an IntlCalendar object -- in this
  case, the IntlCalendar time zone will be used instead. Otherwise,
  the time zone specified in the $timezone argument is used instead.
* Added IntlDateFormatter::getCalendarObject(), which always returns
  the IntlCalendar object that backs the DateFormat, even if a
  constant was passed to the constructor, i.e., if an IntlCalendar
  was not passed to the constructor.
* Added IntlDateFormatter::setTimeZone(). It accepts the usual values
  for time zone arguments. If NULL is passed, the time zone of the
  IntlDateFormatter WILL be overridden with the default time zone,
  even if an IntlCalendar object was passed to the constructor.
* Added IntlDateFormatter::getTimeZone(), which returns the time zone
  that's associated with the DateFormat.
* Depreacated IntlDateFormatter::setTimeZoneId() and made it an alias
  for IntlDateFormatter::setTimeZone(), as the new ::setTimeZone()
  also accepts plain identifiers, besides other types.
  IntlDateFormatter::getTimeZoneId() is not deprecated however.
* IntlDateFormatter::setCalendar() with a constant passed should now
  work correctly. This requires saving the requested locale to the
  constructor.
* Centralized the hacks required to avoid compilation disasters on
  Windows due to some headers being included inside and outside of
  extern "C" blocks.
2012-06-04 00:01:48 +02:00

611 lines
20 KiB
C++

/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Gustavo Lopes <cataphract@php.net> |
+----------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../intl_cppshims.h"
#include <unicode/timezone.h>
#include <unicode/calendar.h>
#include "../intl_convertcpp.h"
extern "C" {
#include "../intl_convert.h"
#define USE_TIMEZONE_POINTER 1
#include "timezone_class.h"
#include "timezone_methods.h"
#include <zend_exceptions.h>
#include <zend_interfaces.h>
#include <ext/date/php_date.h>
}
/* {{{ Global variables */
U_CDECL_BEGIN
zend_class_entry *TimeZone_ce_ptr = NULL;
zend_object_handlers TimeZone_handlers;
U_CDECL_END
/* }}} */
/* {{{ timezone_object_construct */
U_CFUNC void timezone_object_construct(const TimeZone *zone, zval *object, int owned TSRMLS_DC)
{
TimeZone_object *to;
object_init_ex(object, TimeZone_ce_ptr);
TIMEZONE_METHOD_FETCH_OBJECT_NO_CHECK; /* fetch zend object from zval "object" into "to" */
to->utimezone = zone;
to->should_delete = owned;
}
/* }}} */
/* {{{ timezone_convert_datetimezone
* The timezone in DateTime and DateTimeZone is not unified. */
U_CFUNC TimeZone *timezone_convert_datetimezone(int type,
void *object,
int is_datetime,
intl_error *outside_error,
const char *func TSRMLS_DC)
{
char *id = NULL,
offset_id[] = "GMT+00:00";
int id_len = 0;
char *message;
TimeZone *timeZone;
switch (type) {
case TIMELIB_ZONETYPE_ID:
id = is_datetime
? ((php_date_obj*)object)->time->tz_info->name
: ((php_timezone_obj*)object)->tzi.tz->name;
id_len = strlen(id);
break;
case TIMELIB_ZONETYPE_OFFSET: {
int offset_mins = is_datetime
? -((php_date_obj*)object)->time->z
: -(int)((php_timezone_obj*)object)->tzi.utc_offset,
hours = offset_mins / 60,
minutes = offset_mins - hours * 60;
minutes *= minutes > 0 ? 1 : -1;
if (offset_mins <= -24 * 60 || offset_mins >= 24 * 60) {
spprintf(&message, 0, "%s: object has an time zone offset "
"that's too large", func);
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
message, 1 TSRMLS_CC);
efree(message);
return NULL;
}
id = offset_id;
id_len = slprintf(id, sizeof(offset_id), "GMT%+03d:%02d",
hours, minutes);
break;
}
case TIMELIB_ZONETYPE_ABBR:
id = is_datetime
? ((php_date_obj*)object)->time->tz_abbr
: ((php_timezone_obj*)object)->tzi.z.abbr;
id_len = strlen(id);
break;
}
UnicodeString s = UnicodeString(id, id_len, US_INV);
timeZone = TimeZone::createTimeZone(s);
#if U_ICU_VERSION_MAJOR_NUM >= 49
if (*timeZone == TimeZone::getUnknown()) {
#else
UnicodeString resultingId;
timeZone->getID(resultingId);
if (resultingId == UnicodeString("Etc/Unknown", -1, US_INV)
|| resultingId == UnicodeString("GMT", -1, US_INV)) {
#endif
spprintf(&message, 0, "%s: time zone id '%s' "
"extracted from ext/date DateTimeZone not recognized", func, id);
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
message, 1 TSRMLS_CC);
efree(message);
delete timeZone;
return NULL;
}
return timeZone;
}
/* }}} */
/* {{{ 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;
zval arg = zval_used_for_init;
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! */
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;
}
}
if (0) {
error:
if (ret) {
zval_ptr_dtor(&ret);
}
ret = NULL;
}
if (message) {
efree(message);
}
if (Z_TYPE(arg) == IS_STRING) {
zval_dtor(&arg);
}
return ret;
}
/* }}} */
/* {{{ 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,
intl_error *outside_error,
const char *func TSRMLS_DC)
{
zval local_zv_tz = zval_used_for_init,
*local_zv_tz_p = &local_zv_tz;
char *message = NULL;
TimeZone *timeZone;
if (zv_timezone == NULL || Z_TYPE_PP(zv_timezone) == IS_NULL) {
timelib_tzinfo *tzinfo = get_timezone_info(TSRMLS_C);
ZVAL_STRING(&local_zv_tz, tzinfo->name, 0);
zv_timezone = &local_zv_tz_p;
}
if (Z_TYPE_PP(zv_timezone) == IS_OBJECT &&
instanceof_function(Z_OBJCE_PP(zv_timezone), TimeZone_ce_ptr TSRMLS_CC)) {
TimeZone_object *to = (TimeZone_object*)zend_objects_get_address(
*zv_timezone TSRMLS_CC);
if (to->utimezone == NULL) {
spprintf(&message, 0, "%s: passed IntlTimeZone is not "
"properly constructed", func);
if (message) {
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
efree(message);
}
return NULL;
}
timeZone = to->utimezone->clone();
if (timeZone == NULL) {
spprintf(&message, 0, "%s: could not clone TimeZone", func);
if (message) {
intl_errors_set(outside_error, U_MEMORY_ALLOCATION_ERROR, message, 1 TSRMLS_CC);
efree(message);
}
return NULL;
}
} else if (Z_TYPE_PP(zv_timezone) == IS_OBJECT &&
instanceof_function(Z_OBJCE_PP(zv_timezone), php_date_get_timezone_ce() TSRMLS_CC)) {
php_timezone_obj *tzobj = (php_timezone_obj *)zend_objects_get_address(
*zv_timezone TSRMLS_CC);
return timezone_convert_datetimezone(tzobj->type, tzobj, 0,
outside_error, func TSRMLS_CC);
} else {
UnicodeString id,
gottenId;
UErrorCode status = U_ZERO_ERROR; /* outside_error may be NULL */
convert_to_string_ex(zv_timezone);
if (intl_stringFromChar(id, Z_STRVAL_PP(zv_timezone), Z_STRLEN_PP(zv_timezone),
&status) == FAILURE) {
spprintf(&message, 0, "%s: Time zone identifier given is not a "
"valid UTF-8 string", func);
if (message) {
intl_errors_set(outside_error, status, message, 1 TSRMLS_CC);
efree(message);
}
return NULL;
}
timeZone = TimeZone::createTimeZone(id);
if (timeZone == NULL) {
spprintf(&message, 0, "%s: could not create time zone", func);
if (message) {
intl_errors_set(outside_error, U_MEMORY_ALLOCATION_ERROR, message, 1 TSRMLS_CC);
efree(message);
}
return NULL;
}
if (timeZone->getID(gottenId) != id) {
spprintf(&message, 0, "%s: no such time zone: '%s'",
func, Z_STRVAL_PP(zv_timezone));
if (message) {
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
efree(message);
}
delete timeZone;
return NULL;
}
}
return timeZone;
}
/* }}} */
/* {{{ clone handler for TimeZone */
static zend_object_value TimeZone_clone_obj(zval *object TSRMLS_DC)
{
TimeZone_object *to_orig,
*to_new;
zend_object_value ret_val;
intl_error_reset(NULL TSRMLS_CC);
to_orig = (TimeZone_object*)zend_object_store_get_object(object TSRMLS_CC);
intl_error_reset(TIMEZONE_ERROR_P(to_orig) TSRMLS_CC);
ret_val = TimeZone_ce_ptr->create_object(TimeZone_ce_ptr TSRMLS_CC);
to_new = (TimeZone_object*)zend_object_store_get_object_by_handle(
ret_val.handle TSRMLS_CC);
zend_objects_clone_members(&to_new->zo, ret_val,
&to_orig->zo, Z_OBJ_HANDLE_P(object) TSRMLS_CC);
if (to_orig->utimezone != NULL) {
TimeZone *newTimeZone;
newTimeZone = to_orig->utimezone->clone();
to_new->should_delete = 1;
if (!newTimeZone) {
char *err_msg;
intl_errors_set_code(TIMEZONE_ERROR_P(to_orig),
U_MEMORY_ALLOCATION_ERROR TSRMLS_CC);
intl_errors_set_custom_msg(TIMEZONE_ERROR_P(to_orig),
"Could not clone IntlTimeZone", 0 TSRMLS_CC);
err_msg = intl_error_get_message(TIMEZONE_ERROR_P(to_orig) TSRMLS_CC);
zend_throw_exception(NULL, err_msg, 0 TSRMLS_CC);
efree(err_msg);
} else {
to_new->utimezone = newTimeZone;
}
} else {
zend_throw_exception(NULL, "Cannot clone unconstructed IntlTimeZone", 0 TSRMLS_CC);
}
return ret_val;
}
/* }}} */
/* {{{ compare_objects handler for TimeZone
* Can't be used for >, >=, <, <= comparisons */
static int TimeZone_compare_objects(zval *object1, zval *object2 TSRMLS_DC)
{
TimeZone_object *to1,
*to2;
to1 = (TimeZone_object*)zend_object_store_get_object(object1 TSRMLS_CC);
to2 = (TimeZone_object*)zend_object_store_get_object(object2 TSRMLS_CC);
if (to1->utimezone == NULL || to2->utimezone == NULL) {
zend_throw_exception(NULL, "Comparison with at least one unconstructed "
"IntlTimeZone operand", 0 TSRMLS_CC);
/* intentionally not returning */
} else {
if (*to1->utimezone == *to2->utimezone) {
return 0;
}
}
return 1;
}
/* }}} */
/* {{{ get_debug_info handler for TimeZone */
static HashTable *TimeZone_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
{
zval zv = zval_used_for_init;
TimeZone_object *to;
const TimeZone *tz;
UnicodeString ustr;
char *str;
int str_len;
UErrorCode uec = U_ZERO_ERROR;
*is_temp = 1;
array_init_size(&zv, 4);
to = (TimeZone_object*)zend_object_store_get_object(object TSRMLS_CC);
tz = to->utimezone;
if (tz == NULL) {
add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 0);
return Z_ARRVAL(zv);
}
add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 1);
tz->getID(ustr);
intl_convert_utf16_to_utf8(&str, &str_len,
ustr.getBuffer(), ustr.length(), &uec);
if (U_FAILURE(uec)) {
return Z_ARRVAL(zv);
}
add_assoc_stringl_ex(&zv, "id", sizeof("id"), str, str_len, 0);
int32_t rawOffset, dstOffset;
UDate now = Calendar::getNow();
tz->getOffset(now, FALSE, rawOffset, dstOffset, uec);
if (U_FAILURE(uec)) {
return Z_ARRVAL(zv);
}
add_assoc_long_ex(&zv, "rawOffset", sizeof("rawOffset"), (long)rawOffset);
add_assoc_long_ex(&zv, "currentOffset", sizeof("currentOffset"),
(long)(rawOffset + dstOffset));
return Z_ARRVAL(zv);
}
/* }}} */
/* {{{ void TimeZone_object_init(TimeZone_object* to)
* Initialize internals of TImeZone_object not specific to zend standard objects.
*/
static void TimeZone_object_init(TimeZone_object *to TSRMLS_DC)
{
intl_error_init(TIMEZONE_ERROR_P(to) TSRMLS_CC);
to->utimezone = NULL;
to->should_delete = 0;
}
/* }}} */
/* {{{ TimeZone_objects_dtor */
static void TimeZone_objects_dtor(zend_object *object,
zend_object_handle handle TSRMLS_DC)
{
zend_objects_destroy_object(object, handle TSRMLS_CC);
}
/* }}} */
/* {{{ TimeZone_objects_free */
static void TimeZone_objects_free(zend_object *object TSRMLS_DC)
{
TimeZone_object* to = (TimeZone_object*) object;
if (to->utimezone && to->should_delete) {
delete to->utimezone;
to->utimezone = NULL;
}
intl_error_reset(TIMEZONE_ERROR_P(to) TSRMLS_CC);
zend_object_std_dtor(&to->zo TSRMLS_CC);
efree(to);
}
/* }}} */
/* {{{ TimeZone_object_create */
static zend_object_value TimeZone_object_create(zend_class_entry *ce TSRMLS_DC)
{
zend_object_value retval;
TimeZone_object* intern;
intern = (TimeZone_object*)ecalloc(1, sizeof(TimeZone_object));
zend_object_std_init(&intern->zo, ce TSRMLS_CC);
#if PHP_VERSION_ID < 50399
zend_hash_copy(intern->zo.properties, &(ce->default_properties),
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
#else
object_properties_init((zend_object*) intern, ce);
#endif
TimeZone_object_init(intern TSRMLS_CC);
retval.handle = zend_objects_store_put(
intern,
(zend_objects_store_dtor_t) TimeZone_objects_dtor,
(zend_objects_free_object_storage_t) TimeZone_objects_free,
NULL TSRMLS_CC);
retval.handlers = &TimeZone_handlers;
return retval;
}
/* }}} */
/* {{{ TimeZone methods arguments info */
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()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_countEquivalentIDs, 0, 0, 1)
ZEND_ARG_INFO(0, zoneId)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_createTimeZoneIDEnumeration, 0, 0, 1)
ZEND_ARG_INFO(0, zoneType)
ZEND_ARG_INFO(0, region)
ZEND_ARG_INFO(0, rawOffset)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getCanonicalID, 0, 0, 1)
ZEND_ARG_INFO(0, zoneId)
ZEND_ARG_INFO(1, isSystemID)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getEquivalentID, 0, 0, 2)
ZEND_ARG_INFO(0, zoneId)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getOffset, 0, 0, 4)
ZEND_ARG_INFO(0, date)
ZEND_ARG_INFO(0, local)
ZEND_ARG_INFO(1, rawOffset)
ZEND_ARG_INFO(1, dstOffset)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_hasSameRules, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, otherTimeZone, IntlTimeZone, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getDisplayName, 0, 0, 0)
ZEND_ARG_INFO(0, isDaylight)
ZEND_ARG_INFO(0, style)
ZEND_ARG_INFO(0, locale)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_void, 0, 0, 0)
ZEND_END_ARG_INFO()
/* }}} */
/* {{{ TimeZone_class_functions
* Every 'IntlTimeZone' class method has an entry in this table
*/
static zend_function_entry TimeZone_class_functions[] = {
PHP_ME(IntlTimeZone, __construct, ainfo_tz_void, ZEND_ACC_PRIVATE)
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
PHP_ME_MAPPING(getUnknown, intltz_get_unknown, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#endif
PHP_ME_MAPPING(createEnumeration, intltz_create_enumeration, ainfo_tz_createEnumeration, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME_MAPPING(countEquivalentIDs, intltz_count_equivalent_ids, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
PHP_ME_MAPPING(createTimeZoneIDEnumeration, intltz_create_time_zone_id_enumeration, ainfo_tz_createTimeZoneIDEnumeration, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#endif
PHP_ME_MAPPING(getCanonicalID, intltz_get_canonical_id, ainfo_tz_getCanonicalID, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
PHP_ME_MAPPING(getRegion, intltz_get_region, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
#endif
PHP_ME_MAPPING(getTZDataVersion, intltz_get_tz_data_version, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME_MAPPING(getEquivalentID, intltz_get_equivalent_id, ainfo_tz_getEquivalentID, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME_MAPPING(getID, intltz_get_id, ainfo_tz_void, ZEND_ACC_PUBLIC)
PHP_ME_MAPPING(useDaylightTime, intltz_use_daylight_time, ainfo_tz_void, ZEND_ACC_PUBLIC)
PHP_ME_MAPPING(getOffset, intltz_get_offset, ainfo_tz_getOffset, ZEND_ACC_PUBLIC)
PHP_ME_MAPPING(getRawOffset, intltz_get_raw_offset, ainfo_tz_void, ZEND_ACC_PUBLIC)
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
};
/* }}} */
/* {{{ timezone_register_IntlTimeZone_class
* Initialize 'IntlTimeZone' class
*/
U_CFUNC void timezone_register_IntlTimeZone_class(TSRMLS_D)
{
zend_class_entry ce;
/* Create and register 'IntlTimeZone' class. */
INIT_CLASS_ENTRY(ce, "IntlTimeZone", TimeZone_class_functions);
ce.create_object = TimeZone_object_create;
TimeZone_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
if (!TimeZone_ce_ptr) {
//can't happen now without bigger problems before
php_error_docref0(NULL TSRMLS_CC, E_ERROR,
"IntlTimeZone: class registration has failed.");
return;
}
memcpy(&TimeZone_handlers, zend_get_std_object_handlers(),
sizeof TimeZone_handlers);
TimeZone_handlers.clone_obj = TimeZone_clone_obj;
TimeZone_handlers.compare_objects = TimeZone_compare_objects;
TimeZone_handlers.get_debug_info = TimeZone_get_debug_info;
/* Declare 'IntlTimeZone' class constants */
#define TIMEZONE_DECL_LONG_CONST(name, val) \
zend_declare_class_constant_long(TimeZone_ce_ptr, name, sizeof(name) - 1, \
val TSRMLS_CC)
TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT", TimeZone::SHORT);
TIMEZONE_DECL_LONG_CONST("DISPLAY_LONG", TimeZone::LONG);
#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT_GENERIC", TimeZone::SHORT_GENERIC);
TIMEZONE_DECL_LONG_CONST("DISPLAY_LONG_GENERIC", TimeZone::LONG_GENERIC);
TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT_GMT", TimeZone::SHORT_GMT);
TIMEZONE_DECL_LONG_CONST("DISPLAY_LONG_GMT", TimeZone::LONG_GMT);
TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT_COMMONLY_USED", TimeZone::SHORT_COMMONLY_USED);
TIMEZONE_DECL_LONG_CONST("DISPLAY_GENERIC_LOCATION", TimeZone::GENERIC_LOCATION);
#endif
#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
TIMEZONE_DECL_LONG_CONST("TYPE_ANY", UCAL_ZONE_TYPE_ANY);
TIMEZONE_DECL_LONG_CONST("TYPE_CANONICAL", UCAL_ZONE_TYPE_CANONICAL);
TIMEZONE_DECL_LONG_CONST("TYPE_CANONICAL_LOCATION", UCAL_ZONE_TYPE_CANONICAL_LOCATION);
#endif
/* Declare 'IntlTimeZone' class properties */
}
/* }}} */