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.
This commit is contained in:
Gustavo André dos Santos Lopes 2012-04-06 21:52:43 +02:00
parent 9a35d45a5b
commit 81278e1bbb
6 changed files with 216 additions and 0 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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 )

View File

@ -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"

View File

@ -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