Permalink
Browse files

Added IntlCalendar::toDateTime()

  • Loading branch information...
1 parent 49b1f58 commit 3a81f90ebc51140484c617539b1a5fb0e117f4e2 @cataphract committed May 17, 2012
@@ -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
@@ -1200,6 +1200,86 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time)
}
}
+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;
@@ -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
@@ -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 )
@@ -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);
@@ -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==
@@ -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

0 comments on commit 3a81f90

Please sign in to comment.