diff options
author | Gustavo André dos Santos Lopes <cataphract@php.net> | 2012-04-06 21:52:43 +0200 |
---|---|---|
committer | Gustavo André dos Santos Lopes <cataphract@php.net> | 2012-05-17 17:23:47 +0200 |
commit | 81278e1bbbc855f82a8f9a6da7c013a1cc952c09 (patch) | |
tree | 2298c65087bd1c1823e7705a456d8bffe2fc6c7d /ext/intl | |
parent | 9a35d45a5b2226750e198042201e63a37c127f31 (diff) | |
download | php-git-81278e1bbbc855f82a8f9a6da7c013a1cc952c09.tar.gz |
Added IntlCalendar::fromDateTime()
IntlCalendar::fromDateTime(DateTime|string $dateTime[, string $locale)
intlcal_from_date_time(...)
If a string is given as the first argument, the method will try to
instantiate a new DateTime object and use that instead.
Diffstat (limited to 'ext/intl')
-rw-r--r-- | ext/intl/calendar/calendar_class.cpp | 5 | ||||
-rw-r--r-- | ext/intl/calendar/calendar_methods.cpp | 91 | ||||
-rw-r--r-- | ext/intl/calendar/calendar_methods.h | 2 | ||||
-rwxr-xr-x | ext/intl/php_intl.c | 5 | ||||
-rw-r--r-- | ext/intl/tests/calendar_fromDateTime_basic.phpt | 52 | ||||
-rw-r--r-- | ext/intl/tests/calendar_fromDateTime_error.phpt | 61 |
6 files changed, 216 insertions, 0 deletions
diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp index ea5339d836..9f5db6f29c 100644 --- a/ext/intl/calendar/calendar_class.cpp +++ b/ext/intl/calendar/calendar_class.cpp @@ -351,6 +351,10 @@ ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_setLenient, 0, 0, 1) ZEND_ARG_INFO(0, isLenient) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_from_date_time, 0, 0, 1) + ZEND_ARG_INFO(0, dateTime) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_wall_time_option, 0, 0, 1) ZEND_ARG_INFO(0, wallTimeOption) ZEND_END_ARG_INFO() @@ -426,6 +430,7 @@ static const zend_function_entry Calendar_class_functions[] = { PHP_ME_MAPPING(setRepeatedWallTimeOption,intlcal_set_repeated_wall_time_option,ainfo_cal_wall_time_option,ZEND_ACC_PUBLIC) PHP_ME_MAPPING(setSkippedWallTimeOption,intlcal_set_skipped_wall_time_option,ainfo_cal_wall_time_option,ZEND_ACC_PUBLIC) #endif + PHP_ME_MAPPING(fromDateTime, intlcal_from_date_time, ainfo_cal_from_date_time, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC) PHP_ME_MAPPING(getErrorCode, intlcal_get_error_code, ainfo_cal_void, ZEND_ACC_PUBLIC) PHP_ME_MAPPING(getErrorMessage, intlcal_get_error_message, ainfo_cal_void, ZEND_ACC_PUBLIC) PHP_FE_END diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index 0c6450fce7..e9565fc121 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -1108,6 +1108,97 @@ U_CFUNC PHP_FUNCTION(intlcal_set_skipped_wall_time_option) #endif +U_CFUNC PHP_FUNCTION(intlcal_from_date_time) +{ + zval **zv_arg, + *zv_datetime = NULL, + *zv_timestamp = NULL; + php_date_obj *datetime; + char *locale_str = NULL; + int locale_str_len; + TimeZone *timeZone; + UErrorCode status = U_ZERO_ERROR; + 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) { + 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 (!zv_timestamp || Z_TYPE_P(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); + 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)); + } + + Calendar *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_P(zv_timestamp)) * 1000., status); + if (U_FAILURE(status)) { + 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); + } + if (zv_timestamp) { + zval_ptr_dtor(&zv_timestamp); + } +} + U_CFUNC PHP_FUNCTION(intlcal_get_error_code) { CALENDAR_METHOD_INIT_VARS; diff --git a/ext/intl/calendar/calendar_methods.h b/ext/intl/calendar/calendar_methods.h index 95ff5375b5..e0055711ae 100644 --- a/ext/intl/calendar/calendar_methods.h +++ b/ext/intl/calendar/calendar_methods.h @@ -101,6 +101,8 @@ PHP_FUNCTION(intlcal_set_repeated_wall_time_option); PHP_FUNCTION(intlcal_set_skipped_wall_time_option); +PHP_FUNCTION(intlcal_from_date_time); + PHP_FUNCTION(intlcal_get_error_code); PHP_FUNCTION(intlcal_get_error_message); diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c index aca3590e01..51aece69d5 100755 --- a/ext/intl/php_intl.c +++ b/ext/intl/php_intl.c @@ -556,6 +556,10 @@ ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_set_lenient, 0, 0, 2 ) ZEND_ARG_INFO( 0, isLenient ) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_from_date_time, 0, 0, 1) + ZEND_ARG_INFO(0, dateTime) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_wall_time_option, 0, 0, 2 ) ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 ) ZEND_ARG_INFO( 0, wallTimeOption ) @@ -785,6 +789,7 @@ zend_function_entry intl_functions[] = { PHP_FE( intlcal_set_first_day_of_week, ainfo_cal_dow ) PHP_FE( intlcal_set_lenient, ainfo_cal_set_lenient ) PHP_FE( intlcal_equals, ainfo_cal_other_cal ) + PHP_FE( intlcal_from_date_time, ainfo_cal_from_date_time ) #if U_ICU_VERSION_MAJOR_NUM >= 49 PHP_FE( intlcal_get_repeated_wall_time_option, ainfo_cal_only_cal ) PHP_FE( intlcal_get_skipped_wall_time_option, ainfo_cal_only_cal ) diff --git a/ext/intl/tests/calendar_fromDateTime_basic.phpt b/ext/intl/tests/calendar_fromDateTime_basic.phpt new file mode 100644 index 0000000000..1863b7815c --- /dev/null +++ b/ext/intl/tests/calendar_fromDateTime_basic.phpt @@ -0,0 +1,52 @@ +--TEST-- +IntlCalendar::fromDateTime(): basic test +--SKIPIF-- +<?php +if (!extension_loaded('intl')) + die('skip intl extension not enabled'); +--FILE-- +<?php +ini_set("intl.error_level", E_WARNING); +ini_set("intl.default_locale", "nl_NL"); +date_default_timezone_set('Europe/Lisbon'); + +$cal = IntlCalendar::fromDateTime('2012-01-01 00:00:00 Europe/Rome'); +var_dump( + $cal->getTime(), + strtotime('2012-01-01 00:00:00 Europe/Rome') * 1000., + $cal->getTimeZone()->getID(), + $cal->getLocale(1) +); +echo "\n"; + +$cal = IntlCalendar::fromDateTime(new DateTime('2012-01-01 00:00:00 PST'), "pt_PT"); +var_dump( + $cal->getTime(), + strtotime('2012-01-01 00:00:00 PST') * 1000., + $cal->getTimeZone()->getID(), + $cal->getLocale(1) +); + +echo "\n"; + +$cal = intlcal_from_date_time(new DateTime('2012-01-01 00:00:00 +03:40')); +var_dump( + $cal->getTime(), + strtotime('2012-01-01 00:00:00 +03:40') * 1000., + $cal->getTimeZone()->getID() +); + +--EXPECTF-- +float(1325372400000) +float(1325372400000) +string(11) "Europe/Rome" +string(5) "nl_NL" + +float(1325404800000) +float(1325404800000) +string(3) "PST" +string(5) "pt_PT" + +float(1325362800000) +float(1325362800000) +string(%d) "GMT+03%S40" diff --git a/ext/intl/tests/calendar_fromDateTime_error.phpt b/ext/intl/tests/calendar_fromDateTime_error.phpt new file mode 100644 index 0000000000..b3cb22a6ca --- /dev/null +++ b/ext/intl/tests/calendar_fromDateTime_error.phpt @@ -0,0 +1,61 @@ +--TEST-- +IntlCalendar::fromDateTime(): errors +--SKIPIF-- +<?php +if (!extension_loaded('intl')) + die('skip intl extension not enabled'); +--FILE-- +<?php +ini_set("intl.error_level", E_WARNING); +ini_set("intl.default_locale", "nl"); +date_default_timezone_set('Europe/Lisbon'); + +var_dump(IntlCalendar::fromDateTime()); +var_dump(IntlCalendar::fromDateTime(0,1,2)); + +try { +IntlCalendar::fromDateTime("foobar"); +} catch (Exception $e) { + echo "threw exception, OK"; +} +class A extends DateTime { +function __construct() {} +} + +var_dump(IntlCalendar::fromDateTime(new A)); + +$date = new DateTime('2012-01-01 00:00:00 +24:00'); +var_dump(IntlCalendar::fromDateTime($date)); + +$date = new DateTime('2012-01-01 00:00:00 WEST'); +var_dump(IntlCalendar::fromDateTime($date)); + +var_dump(intlcal_from_date_time()); + +--EXPECTF-- + +Warning: IntlCalendar::fromDateTime() expects at least 1 parameter, 0 given in %s on line %d + +Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: bad arguments in %s on line %d +NULL + +Warning: IntlCalendar::fromDateTime() expects at most 2 parameters, 3 given in %s on line %d + +Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: bad arguments in %s on line %d +NULL +threw exception, OK +Warning: DateTime::getTimestamp(): The DateTime object has not been correctly initialized by its constructor in %s on line %d + +Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: bad DateTime; call to DateTime::getTimestamp() failed in %s on line %d +NULL + +Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: object has an time zone offset that's too large in %s on line %d +NULL + +Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d +NULL + +Warning: intlcal_from_date_time() expects at least 1 parameter, 0 given in %s on line %d + +Warning: intlcal_from_date_time(): intlcal_from_date_time: bad arguments in %s on line %d +NULL |