Merge remote branch 'github/intl_calendar'

This commit is contained in:
Gustavo André dos Santos Lopes 2012-05-20 19:50:17 +01:00
commit d9ca243212
28 changed files with 989 additions and 41 deletions

View File

@ -316,8 +316,8 @@ ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_add, 0, 0, 2)
ZEND_ARG_INFO(0, amount)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_setTimeZone, 0, 0, 2)
ZEND_ARG_OBJ_INFO(0, timeZone, IntlTimeZone, 1)
ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_setTimeZone, 0, 0, 1)
ZEND_ARG_INFO(0, timeZone)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_set, 0, 0, 2)
@ -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,8 @@ 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(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

@ -62,6 +62,7 @@ void calendar_register_IntlCalendar_class(TSRMLS_D);
extern zend_class_entry *Calendar_ce_ptr,
*GregorianCalendar_ce_ptr;
extern zend_object_handlers Calendar_handlers;
#endif /* #ifndef CALENDAR_CLASS_H */

View File

@ -30,6 +30,9 @@ extern "C" {
#include "../intl_convert.h"
#include "../locale/locale.h"
#include <zend_exceptions.h>
#include <zend_interfaces.h>
#define _MSC_STDINT_H_ /* avoid redefinitions */
#include <ext/date/php_date.h>
}
#include "../common/common_enum.h"
@ -56,7 +59,7 @@ U_CFUNC PHP_FUNCTION(intlcal_create_instance)
RETURN_NULL();
}
timeZone = timezone_process_timezone_argument(zv_timezone,
timeZone = timezone_process_timezone_argument(zv_timezone, NULL,
"intlcal_create_instance" TSRMLS_CC);
if (timeZone == NULL) {
RETURN_NULL();
@ -323,11 +326,10 @@ U_CFUNC PHP_FUNCTION(intlcal_set_time_zone)
{
zval *zv_timezone;
TimeZone *timeZone;
TimeZone_object *tzo;
CALENDAR_METHOD_INIT_VARS;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
"OO!", &object, Calendar_ce_ptr, &zv_timezone, TimeZone_ce_ptr) == FAILURE) {
"Oz!", &object, Calendar_ce_ptr, &zv_timezone) == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"intlcal_set_time_zone: bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
@ -338,18 +340,10 @@ U_CFUNC PHP_FUNCTION(intlcal_set_time_zone)
if (zv_timezone == NULL) {
RETURN_TRUE; /* the method does nothing if passed null */
}
tzo = static_cast<TimeZone_object*>(
zend_object_store_get_object(zv_timezone TSRMLS_CC));
if (tzo->utimezone == NULL) {
intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR,
"intlcal_set_time_zone: found unsconstructed IntlTimeZone", 0 TSRMLS_CC);
RETURN_FALSE;
}
timeZone = tzo->utimezone->clone();
timeZone = timezone_process_timezone_argument(&zv_timezone,
CALENDAR_ERROR_P(co), "intlcal_set_time_zone" TSRMLS_CC);
if (timeZone == NULL) {
intl_errors_set(&co->err, U_MEMORY_ALLOCATION_ERROR,
"intlcal_set_time_zone: error cloning ICU TimeZone", 0 TSRMLS_CC);
RETURN_FALSE;
}
@ -1114,6 +1108,178 @@ 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->time) {
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)) {
/* time zone was adopted by cal; should not be deleted here */
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_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

@ -101,6 +101,10 @@ 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_to_date_time);
PHP_FUNCTION(intlcal_get_error_code);
PHP_FUNCTION(intlcal_get_error_message);

View File

@ -88,7 +88,7 @@ static void _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAMETERS)
if (variant <= 2) {
// From timezone and locale (0 to 2 arguments)
TimeZone *tz = timezone_process_timezone_argument(tz_object,
TimeZone *tz = timezone_process_timezone_argument(tz_object, NULL,
"intlgregcal_create_instance" TSRMLS_CC);
if (tz == NULL) {
RETURN_NULL();

View File

@ -48,9 +48,16 @@ int intl_stringFromChar(UnicodeString &ret, char *str, int32_t str_len, UErrorCo
}
/* }}} */
/* {{{ intl_charFromString */
/* {{{ intl_charFromString
* faster than doing intl_convert_utf16_to_utf8(&res, &res_len,
* from.getBuffer(), from.length(), &status),
* but consumes more memory */
int intl_charFromString(const UnicodeString &from, char **res, int *res_len, UErrorCode *status)
{
if (from.isBogus()) {
return FAILURE;
}
//the number of UTF-8 code units is not larger than that of UTF-16 code
//units * 3 + 1 for the terminator
int32_t capacity = from.length() * 3 + 1;

View File

@ -29,9 +29,10 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC )
if( !mf_data )
return;
mf_data->umsgf = NULL;
mf_data->orig_format = NULL;
mf_data->arg_types = NULL;
mf_data->umsgf = NULL;
mf_data->orig_format = NULL;
mf_data->arg_types = NULL;
mf_data->tz_set = 0;
intl_error_reset( &mf_data->error TSRMLS_CC );
}
/* }}} */

View File

@ -32,6 +32,7 @@ typedef struct {
char* orig_format;
ulong orig_format_len;
HashTable* arg_types;
int tz_set; /* if we've already the time zone in sub-formats */
} msgformat_data;
msgformat_data* msgformat_data_create( TSRMLS_D );

View File

@ -26,6 +26,9 @@
#include <unicode/msgfmt.h>
#include <unicode/chariter.h>
#include <unicode/ustdio.h>
#include <unicode/timezone.h>
#include <unicode/datefmt.h>
#include <unicode/calendar.h>
#include <vector>
@ -37,9 +40,13 @@ extern "C" {
#include "msgformat_format.h"
#include "msgformat_helpers.h"
#include "intl_convert.h"
#define USE_CALENDAR_POINTER 1
#include "../calendar/calendar_class.h"
/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
#define _MSC_STDINT_H_ 1
#include "ext/date/php_date.h"
#define USE_TIMEZONE_POINTER
#include "../timezone/timezone_class.h"
}
#ifndef INFINITY
@ -130,6 +137,14 @@ static double umsg_helper_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC)
rv = U_MILLIS_PER_SECOND * (double)Z_LVAL(retval);
}
zval_ptr_dtor(&zfuncname);
} else if (instanceof_function(Z_OBJCE_P(z), Calendar_ce_ptr TSRMLS_CC)) {
Calendar_object *co = (Calendar_object *)
zend_object_store_get_object(z TSRMLS_CC );
if (co->ucal == NULL) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
} else {
rv = (double)co->ucal->getTime(*status);
}
} else {
/* TODO: try with cast(), get() to obtain a number */
*status = U_ILLEGAL_ARGUMENT_ERROR;
@ -368,6 +383,55 @@ static HashTable *umsg_get_types(MessageFormatter_object *mfo,
#endif
}
static void umsg_set_timezone(MessageFormatter_object *mfo,
intl_error& err TSRMLS_DC)
{
MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
TimeZone *used_tz = NULL;
const Format **formats;
int32_t count;
/* Unfortanely, this cannot change the time zone for arguments that
* appear inside complex formats because ::getFormats() returns NULL
* for all uncached formats, which is the case for complex formats
* unless they were set via one of the ::setFormat() methods */
if (mfo->mf_data.tz_set) {
return; /* already done */
}
formats = mf->getFormats(count);
if (formats == NULL) {
intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR,
"Out of memory retrieving subformats", 0 TSRMLS_CC);
}
for (int i = 0; U_SUCCESS(err.code) && i < count; i++) {
DateFormat* df = dynamic_cast<DateFormat*>(
const_cast<Format *>(formats[i]));
if (df == NULL) {
continue;
}
if (used_tz == NULL) {
zval nullzv = zval_used_for_init,
*zvptr = &nullzv;
used_tz = timezone_process_timezone_argument(&zvptr, &err,
"msgfmt_format" TSRMLS_CC);
if (used_tz == NULL) {
continue;
}
}
df->setTimeZone(*used_tz);
}
if (U_SUCCESS(err.code)) {
mfo->mf_data.tz_set = 1;
}
}
U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo,
HashTable *args,
UChar **formatted,
@ -385,6 +449,8 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo,
}
types = umsg_get_types(mfo, err TSRMLS_CC);
umsg_set_timezone(mfo, err TSRMLS_CC);
fargs.resize(arg_count);
farg_names.resize(arg_count);

View File

@ -414,6 +414,10 @@ ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_idarg_static, 0, 0, 1 )
ZEND_ARG_INFO( 0, zoneId )
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_from_date_time_zone, 0, 0, 1 )
ZEND_ARG_OBJ_INFO( 0, dateTimeZone, IntlDateTimeZone, 0 )
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_create_enumeration, 0, 0, 0 )
ZEND_ARG_INFO( 0, countryOrRawOffset )
ZEND_END_ARG_INFO()
@ -516,7 +520,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_set_time_zone, 0, 0, 2 )
ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
ZEND_ARG_OBJ_INFO( 0, timeZone, IntlTimeZone, 1 )
ZEND_ARG_INFO( 0, timeZone )
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_set, 0, 0, 3 )
@ -556,6 +560,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 )
@ -715,6 +723,7 @@ zend_function_entry intl_functions[] = {
/* TimeZone functions */
PHP_FE( intltz_create_time_zone, arginfo_tz_idarg_static )
PHP_FE( intltz_from_date_time_zone, arginfo_tz_from_date_time_zone )
PHP_FE( intltz_create_default, arginfo_tz_void )
PHP_FE( intltz_get_id, arginfo_tz_only_tz )
PHP_FE( intltz_get_gmt, arginfo_tz_void )
@ -738,6 +747,7 @@ zend_function_entry intl_functions[] = {
PHP_FE( intltz_has_same_rules, arginfo_tz_has_same_rules )
PHP_FE( intltz_get_display_name, arginfo_tz_get_display_name )
PHP_FE( intltz_get_dst_savings, arginfo_tz_only_tz )
PHP_FE( intltz_to_date_time_zone, arginfo_tz_only_tz )
PHP_FE( intltz_get_error_code, arginfo_tz_only_tz )
PHP_FE( intltz_get_error_message, arginfo_tz_only_tz )
@ -785,6 +795,8 @@ 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 )
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,34 @@
--TEST--
Bug #58756: w.r.t MessageFormatter
--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");
$time = 1247013673;
ini_set('date.timezone', 'America/New_York');
$msgf = new MessageFormatter('en_US', '{0,date,full} {0,time,h:m:s a V}');
echo "date: " . date('l, F j, Y g:i:s A T', $time) . "\n";
echo "msgf: " . $msgf->format(array($time)) . "\n";
//NOT FIXED:
/*$msgf = new MessageFormatter('en_US',
'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}');
echo "msgf2: ", $msgf->format(array($time, 'date')), " ",
$msgf->format(array($time, 'time')), "\n";
*/
?>
==DONE==
--EXPECT--
date: Tuesday, July 7, 2009 8:41:13 PM EDT
msgf: Tuesday, July 7, 2009 8:41:13 PM EDT
==DONE==

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,59 @@
--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: IntlCalendar::fromDateTime(): intlcal_from_date_time: DateTime object is unconstructed 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

View File

@ -20,24 +20,19 @@ echo "error: $errno, $errstr\n";
set_error_handler('eh');
var_dump($c->setTimeZone($gmt, 2));
var_dump($c->setTimeZone(1));
var_dump($c->setTimeZone());
var_dump(intlcal_set_time_zone($c, 1));
var_dump(intlcal_set_time_zone($c, 1, 2));
var_dump(intlcal_set_time_zone(1, $gmt));
--EXPECT--
error: 2, IntlCalendar::setTimeZone() expects exactly 1 parameter, 2 given
error: 2, IntlCalendar::setTimeZone(): intlcal_set_time_zone: bad arguments
bool(false)
error: 4096, Argument 1 passed to IntlCalendar::setTimeZone() must be an instance of IntlTimeZone, integer given
error: 2, IntlCalendar::setTimeZone() expects parameter 1 to be IntlTimeZone, integer given
error: 2, IntlCalendar::setTimeZone(): intlcal_set_time_zone: bad arguments
bool(false)
error: 2, IntlCalendar::setTimeZone() expects exactly 1 parameter, 0 given
error: 2, IntlCalendar::setTimeZone(): intlcal_set_time_zone: bad arguments
bool(false)
error: 4096, Argument 2 passed to intlcal_set_time_zone() must be an instance of IntlTimeZone, integer given
error: 2, intlcal_set_time_zone() expects parameter 2 to be IntlTimeZone, integer given
error: 2, intlcal_set_time_zone() expects exactly 2 parameters, 3 given
error: 2, intlcal_set_time_zone(): intlcal_set_time_zone: bad arguments
bool(false)
error: 4096, Argument 1 passed to intlcal_set_time_zone() must be an instance of IntlCalendar, integer given

View File

@ -0,0 +1,29 @@
--TEST--
IntlCalendar::setTimeZone(): valid time zones for DateTime but not ICU
--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/Amsterdam');
$intlcal = new IntlGregorianCalendar();
$pstdate = new DateTime('2012-01-01 00:00:00 WEST');
$intlcal->setTimeZone($pstdate->getTimeZone());
var_dump($intlcal->getTimeZone()->getID());
$pstdate = new DateTime('2012-01-01 00:00:00 +24:00');
$intlcal->setTimeZone($pstdate->getTimeZone());
var_dump($intlcal->getTimeZone()->getID());
--EXPECTF--
Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d
string(16) "Europe/Amsterdam"
Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: object has an time zone offset that's too large in %s on line %d
string(16) "Europe/Amsterdam"

View File

@ -0,0 +1,30 @@
--TEST--
IntlCalendar::setTimeZone(): different ways to specify time zone
--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/Amsterdam');
$intlcal = new IntlGregorianCalendar();
$intlcal->setTimeZone('Europe/Paris');
var_dump($intlcal->getTimeZone()->getID());
$intlcal->setTimeZone(new DateTimeZone('Europe/Madrid'));
var_dump($intlcal->getTimeZone()->getID());
$pstdate = new DateTime('2012-01-01 00:00:00 PST');
$intlcal->setTimeZone($pstdate->getTimeZone());
var_dump($intlcal->getTimeZone()->getID());
$offsetdate = new DateTime('2012-01-01 00:00:00 -02:30');
$intlcal->setTimeZone($offsetdate->getTimeZone());
var_dump($intlcal->getTimeZone()->getID());
--EXPECTF--
string(12) "Europe/Paris"
string(13) "Europe/Madrid"
string(3) "PST"
string(%d) "GMT-02%S30"

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

View File

@ -0,0 +1,30 @@
--TEST--
MessageFormat accepts IntlCalendar args
--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);
$msgf = new MessageFormatter('pt_PT', '{0,date,full} {0,time,h:m:s a V}');
echo $msgf->format(array($cal)), "\n";
//NOT FIXED:
/*$msgf = new MessageFormatter('en_US',
'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}');
echo "msgf2: ", $msgf->format(array($time, 'date')), " ",
$msgf->format(array($time, 'time')), "\n";
*/
?>
==DONE==
--EXPECT--
Quinta-feira, 17 de Maio de 2012 5:35:36 p.m. WEST
==DONE==

View File

@ -0,0 +1,41 @@
--TEST--
IntlTimeZone::fromDateTimeZone(): 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");
date_default_timezone_set('Europe/Lisbon');
$tz = IntlTimeZone::fromDateTimeZone(new DateTimeZone('Europe/Amsterdam'));
var_dump($tz->getID(), $tz->getRawOffset());
$dt = new DateTime('2012-01-01 00:00:00 CET');
$dtz = $dt->getTimeZone();
/* this is different from new DateTimeZone('CET'),
* which gives a Europe/Berlin timezone */
var_dump($dtz->getName());
$tz = IntlTimeZone::fromDateTimeZone($dtz);
var_dump($tz->getID(), $tz->getRawOffset());
$dt = new DateTime('2012-01-01 00:00:00 +0340');
$dtz = $dt->getTimeZone();
/* I don't think this timezone can be generated without a DateTime object */
var_dump($dtz->getName());
$tz = IntlTimeZone::fromDateTimeZone($dtz);
var_dump($tz->getID(), $tz->getRawOffset() /* (3*60+40)*60000 */);
--EXPECTF--
string(16) "Europe/Amsterdam"
int(3600000)
string(3) "CET"
string(3) "CET"
int(3600000)
string(6) "+03:40"
string(%d) "GMT+03%s0"
int(13200000)

View File

@ -0,0 +1,48 @@
--TEST--
IntlTimeZone::fromDateTimeZone(): argument errors
--SKIPIF--
<?php
if (!extension_loaded('intl'))
die('skip intl extension not enabled');
--FILE--
<?php
ini_set("intl.error_level", E_WARNING);
var_dump(IntlTimeZone::fromDateTimeZone());
var_dump(IntlTimeZone::fromDateTimeZone(1,2));
var_dump(IntlTimeZone::fromDateTimeZone('sdfds'));
var_dump(IntlTimeZone::fromDateTimeZone(new stdclass));
$dt = new DateTime('2012-08-01 00:00:00 WEST');
var_dump(IntlTimeZone::fromDateTimeZone($dt->getTimeZone()));
var_dump(intltz_from_date_time_zone());
--EXPECTF--
Warning: IntlTimeZone::fromDateTimeZone() expects exactly 1 parameter, 0 given in %s on line %d
Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
NULL
Warning: IntlTimeZone::fromDateTimeZone() expects exactly 1 parameter, 2 given in %s on line %d
Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
NULL
Warning: IntlTimeZone::fromDateTimeZone() expects parameter 1 to be DateTimeZone, string given in %s on line %d
Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
NULL
Warning: IntlTimeZone::fromDateTimeZone() expects parameter 1 to be DateTimeZone, object given in %s on line %d
Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
NULL
Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d
NULL
Warning: intltz_from_date_time_zone() expects exactly 1 parameter, 0 given in %s on line %d
Warning: intltz_from_date_time_zone(): intltz_from_date_time_zone: bad arguments in %s on line %d
NULL

View File

@ -0,0 +1,38 @@
--TEST--
IntlTimeZone::toDateTimeZone(): 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");
date_default_timezone_set('Europe/Lisbon');
function do_test(IntlTimeZone $tz, $proc = false) {
var_dump($tz->getID(), $tz->getRawOffset());
if (!$proc)
$dtz = $tz->toDateTimeZone();
else
$dtz = intltz_to_date_time_zone($tz);
var_dump($dtz->getName(), $dtz->getOffset(new DateTime('2012-01-01 00:00:00')));
}
do_test(IntlTimeZone::createTimeZone('CET'));
do_test(IntlTimeZone::createTimeZone('Europe/Amsterdam'));
do_test(IntlTimeZone::createTimeZone('GMT+0405'), true);
--EXPECTF--
string(3) "CET"
int(3600000)
string(13) "Europe/Berlin"
int(3600)
string(16) "Europe/Amsterdam"
int(3600000)
string(16) "Europe/Amsterdam"
int(3600)
string(%s) "GMT+04%s5"
int(14700000)
string(6) "+04:05"
int(14700)

View File

@ -0,0 +1,38 @@
--TEST--
IntlTimeZone::toDateTimeZone(): errors
--SKIPIF--
<?php
if (!extension_loaded('intl'))
die('skip intl extension not enabled');
--FILE--
<?php
ini_set("intl.error_level", E_WARNING);
$tz = IntlTimeZone::createTimeZone('Etc/Unknown');
var_dump($tz->toDateTimeZone(''));
try {
var_dump($tz->toDateTimeZone());
} catch (Exception $e) {
var_dump($e->getMessage());
}
var_dump(intltz_to_date_time_zone());
var_dump(intltz_to_date_time_zone(1));
--EXPECTF--
Warning: IntlTimeZone::toDateTimeZone() expects exactly 0 parameters, 1 given in %s on line %d
Warning: IntlTimeZone::toDateTimeZone(): intltz_to_date_time_zone: bad arguments in %s on line %d
bool(false)
Warning: IntlTimeZone::toDateTimeZone(): intltz_to_date_time_zone: DateTimeZone constructor threw exception in %s on line %d
string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)"
Warning: intltz_to_date_time_zone() expects exactly 1 parameter, 0 given in %s on line %d
Warning: intltz_to_date_time_zone(): intltz_to_date_time_zone: bad arguments in %s on line %d
bool(false)
Catchable fatal error: Argument 1 passed to intltz_to_date_time_zone() must be an instance of IntlTimeZone, integer given in %s on line %d

View File

@ -29,6 +29,7 @@ extern "C" {
#include "timezone_class.h"
#include "timezone_methods.h"
#include <zend_exceptions.h>
#include <zend_interfaces.h>
/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
#define _MSC_STDINT_H_ 1
#include <ext/date/php_date.h>
@ -53,10 +54,155 @@ U_CFUNC void timezone_object_construct(const TimeZone *zone, zval *object, int o
}
/* }}} */
/* {{{ 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)
{
const 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((char*)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 for constructor like functions (sets the global
* error). */
TimeZone *timezone_process_timezone_argument(zval **zv_timezone, const char *func TSRMLS_DC)
* 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;
@ -77,7 +223,7 @@ TimeZone *timezone_process_timezone_argument(zval **zv_timezone, const char *fun
spprintf(&message, 0, "%s: passed IntlTimeZone is not "
"properly constructed", func);
if (message) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
efree(message);
}
return NULL;
@ -86,22 +232,30 @@ TimeZone *timezone_process_timezone_argument(zval **zv_timezone, const char *fun
if (timeZone == NULL) {
spprintf(&message, 0, "%s: could not clone TimeZone", func);
if (message) {
intl_error_set(NULL, U_MEMORY_ALLOCATION_ERROR, message, 1 TSRMLS_CC);
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;
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_error_set(NULL, status, message, 1 TSRMLS_CC);
intl_errors_set(outside_error, status, message, 1 TSRMLS_CC);
efree(message);
}
return NULL;
@ -110,7 +264,7 @@ TimeZone *timezone_process_timezone_argument(zval **zv_timezone, const char *fun
if (timeZone == NULL) {
spprintf(&message, 0, "%s: could not create time zone", func);
if (message) {
intl_error_set(NULL, U_MEMORY_ALLOCATION_ERROR, message, 1 TSRMLS_CC);
intl_errors_set(outside_error, U_MEMORY_ALLOCATION_ERROR, message, 1 TSRMLS_CC);
efree(message);
}
return NULL;
@ -119,7 +273,7 @@ TimeZone *timezone_process_timezone_argument(zval **zv_timezone, const char *fun
spprintf(&message, 0, "%s: no such time zone: '%s'",
func, Z_STRVAL_PP(zv_timezone));
if (message) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
efree(message);
}
delete timeZone;
@ -318,6 +472,10 @@ 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()
@ -369,6 +527,7 @@ ZEND_END_ARG_INFO()
*/
static zend_function_entry TimeZone_class_functions[] = {
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
@ -393,6 +552,7 @@ static zend_function_entry TimeZone_class_functions[] = {
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

View File

@ -59,7 +59,9 @@ typedef struct {
RETURN_FALSE; \
}
TimeZone *timezone_process_timezone_argument(zval **zv_timezone, const char *func TSRMLS_DC);
TimeZone *timezone_convert_datetimezone(int type, void *object, int is_datetime, intl_error *outside_error, const char *func TSRMLS_DC);
zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, const char *func TSRMLS_DC);
TimeZone *timezone_process_timezone_argument(zval **zv_timezone, intl_error *error, const char *func TSRMLS_DC);
void timezone_object_construct(const TimeZone *zone, zval *object, int owned TSRMLS_DC);

View File

@ -28,6 +28,9 @@ extern "C" {
#include "intl_convert.h"
#include "../locale/locale.h"
#include <zend_exceptions.h>
/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
#define _MSC_STDINT_H_ 1
#include <ext/date/php_date.h>
}
#include "common/common_enum.h"
@ -57,6 +60,37 @@ U_CFUNC PHP_FUNCTION(intltz_create_time_zone)
timezone_object_construct(tz, return_value, 1 TSRMLS_CC);
}
U_CFUNC PHP_FUNCTION(intltz_from_date_time_zone)
{
zval *zv_timezone;
TimeZone *tz;
php_timezone_obj *tzobj;
intl_error_reset(NULL TSRMLS_CC);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O",
&zv_timezone, php_date_get_timezone_ce()) == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"intltz_from_date_time_zone: bad arguments", 0 TSRMLS_CC);
RETURN_NULL();
}
tzobj = (php_timezone_obj *)zend_objects_get_address(zv_timezone TSRMLS_CC);
if (!tzobj->initialized) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"intltz_from_date_time_zone: DateTimeZone object is unconstructed",
0 TSRMLS_CC);
RETURN_NULL();
}
tz = timezone_convert_datetimezone(tzobj->type, tzobj, FALSE, NULL,
"intltz_from_date_time_zone" TSRMLS_CC);
if (tz == NULL) {
RETURN_NULL();
}
timezone_object_construct(tz, return_value, 1 TSRMLS_CC);
}
U_CFUNC PHP_FUNCTION(intltz_create_default)
{
intl_error_reset(NULL TSRMLS_CC);
@ -549,6 +583,29 @@ U_CFUNC PHP_FUNCTION(intltz_get_dst_savings)
RETURN_LONG((long)to->utimezone->getDSTSavings());
}
U_CFUNC PHP_FUNCTION(intltz_to_date_time_zone)
{
TIMEZONE_METHOD_INIT_VARS;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
"O", &object, TimeZone_ce_ptr) == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"intltz_to_date_time_zone: bad arguments", 0 TSRMLS_CC);
RETURN_FALSE;
}
TIMEZONE_METHOD_FETCH_OBJECT;
zval *ret = timezone_convert_to_datetimezone(to->utimezone,
&TIMEZONE_ERROR(to), "intltz_to_date_time_zone" TSRMLS_CC);
if (ret) {
RETURN_ZVAL(ret, 1, 1);
} else {
RETURN_FALSE;
}
}
U_CFUNC PHP_FUNCTION(intltz_get_error_code)
{
TIMEZONE_METHOD_INIT_VARS

View File

@ -21,6 +21,8 @@
PHP_FUNCTION(intltz_create_time_zone);
PHP_FUNCTION(intltz_from_date_time_zone);
PHP_FUNCTION(intltz_create_default);
PHP_FUNCTION(intltz_get_id);
@ -55,6 +57,8 @@ PHP_FUNCTION(intltz_get_display_name);
PHP_FUNCTION(intltz_get_dst_savings);
PHP_FUNCTION(intltz_to_date_time_zone);
PHP_FUNCTION(intltz_get_error_code);
PHP_FUNCTION(intltz_get_error_message);