Added IntlCalendar::toDateTime()

This commit is contained in:
Gustavo André dos Santos Lopes 2012-05-17 23:18:51 +02:00
parent 49b1f58194
commit 3a81f90ebc
7 changed files with 152 additions and 1 deletions

View File

@ -431,6 +431,7 @@ static const zend_function_entry Calendar_class_functions[] = {
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(toDateTime, intlcal_to_date_time, ainfo_cal_void, 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

View File

@ -1200,6 +1200,86 @@ error:
}
}
U_CFUNC PHP_FUNCTION(intlcal_to_date_time)
{
zval *retval = NULL;
CALENDAR_METHOD_INIT_VARS;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
&object, Calendar_ce_ptr) == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"intlcal_to_date_time: bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
}
CALENDAR_METHOD_FETCH_OBJECT;
/* There are no exported functions in ext/date to this
* in a more native fashion */
double date = co->ucal->getTime(CALENDAR_ERROR_CODE(co)) / 1000.;
int64_t ts;
char ts_str[sizeof("@-9223372036854775808")];
int ts_str_len;
zval ts_zval = zval_used_for_init;
INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed");
if (date > (double)U_INT64_MAX || date < (double)U_INT64_MIN) {
intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
"intlcal_to_date_time: The calendar date is out of the "
"range for a 64-bit integer", 0 TSRMLS_CC);
RETURN_FALSE;
}
ts = (int64_t)date;
ts_str_len = slprintf(ts_str, sizeof(ts_str), "@%I64d", ts);
ZVAL_STRINGL(&ts_zval, ts_str, ts_str_len, 0);
/* Now get the time zone */
const TimeZone& tz = co->ucal->getTimeZone();
zval *timezone_zval = timezone_convert_to_datetimezone(
&tz, CALENDAR_ERROR_P(co), "intlcal_to_date_time" TSRMLS_CC);
if (timezone_zval == NULL) {
RETURN_FALSE;
}
/* resources allocated from now on */
/* Finally, instantiate object and call constructor */
object_init_ex(return_value, php_date_get_date_ce());
zend_call_method_with_2_params(&return_value, NULL, NULL, "__construct",
NULL, &ts_zval, timezone_zval);
if (EG(exception)) {
intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
"intlcal_to_date_time: DateTime constructor has thrown exception",
1 TSRMLS_CC);
zend_object_store_ctor_failed(return_value TSRMLS_CC);
zval_ptr_dtor(&return_value);
RETVAL_FALSE;
goto error;
}
/* due to bug #40743, we have to set the time zone again */
zend_call_method_with_1_params(&return_value, NULL, NULL, "settimezone",
&retval, timezone_zval);
if (retval == NULL || Z_TYPE_P(retval) == IS_BOOL) {
intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
"intlcal_to_date_time: call to DateTime::setTimeZone has failed",
1 TSRMLS_CC);
zval_ptr_dtor(&return_value);
RETVAL_FALSE;
goto error;
}
error:
zval_ptr_dtor(&timezone_zval);
if (retval != NULL) {
zval_ptr_dtor(&retval);
}
}
U_CFUNC PHP_FUNCTION(intlcal_get_error_code)
{
CALENDAR_METHOD_INIT_VARS;

View File

@ -103,6 +103,8 @@ PHP_FUNCTION(intlcal_set_skipped_wall_time_option);
PHP_FUNCTION(intlcal_from_date_time);
PHP_FUNCTION(intlcal_to_date_time);
PHP_FUNCTION(intlcal_get_error_code);
PHP_FUNCTION(intlcal_get_error_message);

View File

@ -796,6 +796,7 @@ zend_function_entry intl_functions[] = {
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 )
PHP_FE( intlcal_to_date_time, ainfo_cal_only_cal )
#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 )

View File

@ -13,7 +13,10 @@ foreach($funcs as $func) {
if($rfunc->getNumberOfRequiredParameters() == 0) {
continue;
}
$res = $func($arg);
try {
$res = $func($arg);
} catch (Exception $e) { continue; }
if($res != false) {
echo "$func: ";
var_dump($res);

View File

@ -0,0 +1,23 @@
--TEST--
IntlCalendar::toDateTime(): 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");
ini_set('date.timezone', 'Europe/Lisbon');
$cal = new IntlGregorianCalendar(2012,04,17,17,35,36);
$dt = $cal->toDateTime();
var_dump($dt->format("c"), $dt->getTimeZone()->getName());
?>
==DONE==
--EXPECT--
string(25) "2012-05-17T17:35:36+01:00"
string(13) "Europe/Lisbon"
==DONE==

View File

@ -0,0 +1,41 @@
--TEST--
IntlCalendar::toDateTime(): bad arguments
--SKIPIF--
<?php
if (!extension_loaded('intl'))
die('skip intl extension not enabled');
--FILE--
<?php
ini_set("intl.error_level", E_WARNING);
ini_set('date.timezone', 'Europe/Lisbon');
$cal = new IntlGregorianCalendar();
var_dump($cal->toDateTime(3));
var_dump(intlcal_to_date_time($cal, 3));
$cal = new IntlGregorianCalendar("Etc/Unknown");
try {
var_dump($cal->toDateTime());
} catch (Exception $e) {
var_dump("exception: {$e->getMessage()}");
}
var_dump(intlcal_to_date_time(3));
--EXPECTF--
Warning: IntlCalendar::toDateTime() expects exactly 0 parameters, 1 given in %s on line %d
Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: bad arguments in %s on line %d
bool(false)
Warning: intlcal_to_date_time() expects exactly 1 parameter, 2 given in %s on line %d
Warning: intlcal_to_date_time(): intlcal_to_date_time: bad arguments in %s on line %d
bool(false)
Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d
string(77) "exception: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)"
Catchable fatal error: Argument 1 passed to intlcal_to_date_time() must be an instance of IntlCalendar, integer given in %s on line %d