mirror of
https://github.com/php/php-src.git
synced 2024-09-22 18:37:25 +00:00
Unified zval -> UDate conversions
Now IntlDateFormatter::format() also accepts IntlCalendar objects. Code is shared in MessageFormatter and IntlDateFormatter.
This commit is contained in:
parent
758f0686d4
commit
2416719fb1
88
ext/intl/common/common_date.cpp
Normal file
88
ext/intl/common/common_date.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Gustavo Lopes <cataphract@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "../intl_cppshims.h"
|
||||
|
||||
#include <unicode/calendar.h>
|
||||
|
||||
extern "C" {
|
||||
#include "../php_intl.h"
|
||||
#define USE_CALENDAR_POINTER 1
|
||||
#include "../calendar/calendar_class.h"
|
||||
#include <ext/date/php_date.h>
|
||||
}
|
||||
|
||||
U_CFUNC double intl_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC)
|
||||
{
|
||||
double rv = NAN;
|
||||
long lv;
|
||||
int type;
|
||||
|
||||
if (U_FAILURE(*status)) {
|
||||
return NAN;
|
||||
}
|
||||
|
||||
switch (Z_TYPE_P(z)) {
|
||||
case IS_STRING:
|
||||
type = is_numeric_string(Z_STRVAL_P(z), Z_STRLEN_P(z), &lv, &rv, 0);
|
||||
if (type == IS_DOUBLE) {
|
||||
rv *= U_MILLIS_PER_SECOND;
|
||||
} else if (type == IS_LONG) {
|
||||
rv = U_MILLIS_PER_SECOND * (double)lv;
|
||||
} else {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
break;
|
||||
case IS_LONG:
|
||||
rv = U_MILLIS_PER_SECOND * (double)Z_LVAL_P(z);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
rv = U_MILLIS_PER_SECOND * Z_DVAL_P(z);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
if (instanceof_function(Z_OBJCE_P(z), php_date_get_date_ce() TSRMLS_CC)) {
|
||||
zval retval;
|
||||
zval *zfuncname;
|
||||
INIT_ZVAL(retval);
|
||||
MAKE_STD_ZVAL(zfuncname);
|
||||
ZVAL_STRING(zfuncname, "getTimestamp", 1);
|
||||
if (call_user_function(NULL, &(z), zfuncname, &retval, 0, NULL TSRMLS_CC)
|
||||
!= SUCCESS || Z_TYPE(retval) != IS_LONG) {
|
||||
*status = U_INTERNAL_PROGRAM_ERROR;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
29
ext/intl/common/common_date.h
Normal file
29
ext/intl/common/common_date.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Gustavo Lopes <cataphract@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef COMMON_DATE_H
|
||||
#define COMMON_DATE_H
|
||||
|
||||
#include <unicode/umachine.h>
|
||||
|
||||
U_CDECL_BEGIN
|
||||
#include <php.h>
|
||||
U_CDECL_END
|
||||
|
||||
U_CFUNC double intl_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC);
|
||||
|
||||
#endif /* COMMON_DATE_H */
|
||||
|
@ -33,6 +33,7 @@ if test "$PHP_INTL" != "no"; then
|
||||
collator/collator_error.c \
|
||||
common/common_error.c \
|
||||
common/common_enum.cpp \
|
||||
common/common_date.cpp \
|
||||
formatter/formatter.c \
|
||||
formatter/formatter_main.c \
|
||||
formatter/formatter_class.c \
|
||||
|
@ -24,6 +24,7 @@ if (PHP_INTL != "no") {
|
||||
ADD_SOURCES(configure_module_dirname + "/common", "\
|
||||
common_error.c \
|
||||
common_enum.cpp \
|
||||
common_date.cpp \
|
||||
", "intl");
|
||||
ADD_SOURCES(configure_module_dirname + "/formatter", "\
|
||||
formatter.c \
|
||||
|
@ -40,6 +40,5 @@ These are not necessary at this point of time
|
||||
#define CALENDAR_YEAR "tm_year"
|
||||
#define CALENDAR_WDAY "tm_wday"
|
||||
#define CALENDAR_YDAY "tm_yday"
|
||||
#define CALENDAR_ISDST "tm_isdst"
|
||||
|
||||
#endif // DATE_FORMATTER_H
|
||||
|
@ -21,15 +21,13 @@
|
||||
#include <unicode/ustring.h>
|
||||
#include <unicode/ucal.h>
|
||||
|
||||
#include "php_intl.h"
|
||||
#include "intl_convert.h"
|
||||
#include "../php_intl.h"
|
||||
#include "../intl_convert.h"
|
||||
#include "../common/common_date.h"
|
||||
#include "dateformat.h"
|
||||
#include "dateformat_class.h"
|
||||
#include "dateformat_format.h"
|
||||
#include "dateformat_data.h"
|
||||
/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
|
||||
#define _MSC_STDINT_H_ 1
|
||||
#include "ext/date/php_date.h"
|
||||
|
||||
/* {{{
|
||||
* Internal function which calls the udat_format
|
||||
@ -126,70 +124,38 @@ static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, HashTable* ha
|
||||
* Format the time value as a string. }}}*/
|
||||
PHP_FUNCTION(datefmt_format)
|
||||
{
|
||||
UDate timestamp =0;
|
||||
UDate p_timestamp =0;
|
||||
HashTable* hash_arr = NULL;
|
||||
zval* zarg = NULL;
|
||||
UDate timestamp = 0;
|
||||
HashTable *hash_arr = NULL;
|
||||
zval *zarg = NULL;
|
||||
|
||||
DATE_FORMAT_METHOD_INIT_VARS;
|
||||
|
||||
/* Parse parameters. */
|
||||
if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &object, IntlDateFormatter_ce_ptr,&zarg ) == FAILURE )
|
||||
{
|
||||
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable to parse input params", 0 TSRMLS_CC );
|
||||
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz",
|
||||
&object, IntlDateFormatter_ce_ptr, &zarg) == FAILURE) {
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable "
|
||||
"to parse input params", 0 TSRMLS_CC );
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* Fetch the object. */
|
||||
DATE_FORMAT_METHOD_FETCH_OBJECT;
|
||||
|
||||
switch(Z_TYPE_P(zarg) ){
|
||||
case IS_LONG:
|
||||
p_timestamp = Z_LVAL_P(zarg) ;
|
||||
timestamp = p_timestamp * 1000;
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
/* timestamp*1000 since ICU expects it in milliseconds */
|
||||
p_timestamp = Z_DVAL_P(zarg) ;
|
||||
timestamp = p_timestamp * 1000;
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
hash_arr = Z_ARRVAL_P(zarg);
|
||||
if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 )
|
||||
RETURN_FALSE;
|
||||
|
||||
timestamp = internal_get_timestamp(dfo, hash_arr TSRMLS_CC);
|
||||
INTL_METHOD_CHECK_STATUS( dfo, "datefmt_format: Date formatting failed" )
|
||||
break;
|
||||
case IS_OBJECT: {
|
||||
zend_class_entry *date_ce = php_date_get_date_ce();
|
||||
zval retval;
|
||||
zval *zfuncname;
|
||||
if(!instanceof_function(Z_OBJCE_P(zarg), date_ce TSRMLS_CC)) {
|
||||
intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: object must be an instance of DateTime", 0 TSRMLS_CC );
|
||||
RETURN_FALSE;
|
||||
}
|
||||
INIT_ZVAL(retval);
|
||||
MAKE_STD_ZVAL(zfuncname);
|
||||
ZVAL_STRING(zfuncname, "getTimestamp", 1);
|
||||
if(call_user_function(NULL, &zarg, zfuncname, &retval, 0, NULL TSRMLS_CC) != SUCCESS || Z_TYPE(retval) != IS_LONG) {
|
||||
intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: cannot get timestamp", 0 TSRMLS_CC );
|
||||
zval_ptr_dtor(&zfuncname);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
zval_ptr_dtor(&zfuncname);
|
||||
p_timestamp = Z_LVAL(retval);
|
||||
timestamp = p_timestamp*1000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
intl_errors_set( INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"datefmt_format: takes either an array or an integer timestamp value or a DateTime object", 0 TSRMLS_CC );
|
||||
if (Z_TYPE_P(zarg) == IS_ARRAY) {
|
||||
hash_arr = Z_ARRVAL_P(zarg);
|
||||
if (!hash_arr || zend_hash_num_elements(hash_arr) == 0) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
internal_format( dfo, timestamp, return_value TSRMLS_CC);
|
||||
timestamp = internal_get_timestamp(dfo, hash_arr TSRMLS_CC);
|
||||
INTL_METHOD_CHECK_STATUS(dfo, "datefmt_format: date formatting failed")
|
||||
} else {
|
||||
timestamp = intl_zval_to_millis(zarg,
|
||||
&INTL_DATA_ERROR_CODE(dfo) TSRMLS_CC);
|
||||
INTL_METHOD_CHECK_STATUS(dfo, "datefmt_format: could not convert input "
|
||||
"into a date")
|
||||
}
|
||||
|
||||
internal_format( dfo, timestamp, return_value TSRMLS_CC);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../intl_convertcpp.h"
|
||||
#include "../common/common_date.h"
|
||||
|
||||
extern "C" {
|
||||
#include "php_intl.h"
|
||||
@ -38,11 +39,6 @@ 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"
|
||||
}
|
||||
@ -95,66 +91,6 @@ U_CFUNC int32_t umsg_format_arg_count(UMessageFormat *fmt)
|
||||
return fmt_count;
|
||||
}
|
||||
|
||||
static double umsg_helper_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC) {
|
||||
double rv = NAN;
|
||||
long lv;
|
||||
int type;
|
||||
|
||||
if (U_FAILURE(*status)) {
|
||||
return NAN;
|
||||
}
|
||||
|
||||
switch (Z_TYPE_P(z)) {
|
||||
case IS_STRING:
|
||||
type = is_numeric_string(Z_STRVAL_P(z), Z_STRLEN_P(z), &lv, &rv, 0);
|
||||
if (type == IS_DOUBLE) {
|
||||
rv *= U_MILLIS_PER_SECOND;
|
||||
} else if (type == IS_LONG) {
|
||||
rv = U_MILLIS_PER_SECOND * (double)lv;
|
||||
} else {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
break;
|
||||
case IS_LONG:
|
||||
rv = U_MILLIS_PER_SECOND * (double)Z_LVAL_P(z);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
rv = U_MILLIS_PER_SECOND * Z_DVAL_P(z);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
if (instanceof_function(Z_OBJCE_P(z), php_date_get_date_ce() TSRMLS_CC)) {
|
||||
zval retval;
|
||||
zval *zfuncname;
|
||||
INIT_ZVAL(retval);
|
||||
MAKE_STD_ZVAL(zfuncname);
|
||||
ZVAL_STRING(zfuncname, "getTimestamp", 1);
|
||||
if (call_user_function(NULL, &(z), zfuncname, &retval, 0, NULL TSRMLS_CC)
|
||||
!= SUCCESS || Z_TYPE(retval) != IS_LONG) {
|
||||
*status = U_INTERNAL_PROGRAM_ERROR;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static HashTable *umsg_get_numeric_types(MessageFormatter_object *mfo,
|
||||
intl_error& err TSRMLS_DC)
|
||||
{
|
||||
@ -613,7 +549,7 @@ retry_kint64:
|
||||
}
|
||||
case Formattable::kDate:
|
||||
{
|
||||
double dd = umsg_helper_zval_to_millis(*elem, &err.code TSRMLS_CC);
|
||||
double dd = intl_zval_to_millis(*elem, &err.code TSRMLS_CC);
|
||||
if (U_FAILURE(err.code)) {
|
||||
char *message, *key_char;
|
||||
int key_len;
|
||||
|
@ -399,24 +399,24 @@ Formatted DateTime is : 20001230 05:04 PM
|
||||
Date is: stdClass::__set_state(array(
|
||||
))
|
||||
------------
|
||||
Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
Error while formatting as: 'datefmt_format: could not convert input into a date: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
------------
|
||||
Date is: stdClass::__set_state(array(
|
||||
))
|
||||
------------
|
||||
Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
Error while formatting as: 'datefmt_format: could not convert input into a date: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
------------
|
||||
Date is: stdClass::__set_state(array(
|
||||
))
|
||||
------------
|
||||
Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
Error while formatting as: 'datefmt_format: could not convert input into a date: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
------------
|
||||
Date is: stdClass::__set_state(array(
|
||||
))
|
||||
------------
|
||||
Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
Error while formatting as: 'datefmt_format: could not convert input into a date: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
------------
|
||||
Date is: stdClass::__set_state(array(
|
||||
))
|
||||
------------
|
||||
Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
Error while formatting as: 'datefmt_format: could not convert input into a date: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
|
Loading…
Reference in New Issue
Block a user