Now IntlDateFormatter::format() also accepts IntlCalendar objects.
Code is shared in MessageFormatter and IntlDateFormatter.
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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;
+}
+
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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 */
+
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 \
ADD_SOURCES(configure_module_dirname + "/common", "\
common_error.c \
common_enum.cpp \
+ common_date.cpp \
", "intl");
ADD_SOURCES(configure_module_dirname + "/formatter", "\
formatter.c \
#define CALENDAR_YEAR "tm_year"
#define CALENDAR_WDAY "tm_wday"
#define CALENDAR_YDAY "tm_yday"
-#define CALENDAR_ISDST "tm_isdst"
#endif // DATE_FORMATTER_H
#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
* 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);
}
/* }}} */
#include <vector>
#include "../intl_convertcpp.h"
+#include "../common/common_date.h"
extern "C" {
#include "php_intl.h"
#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"
}
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)
{
}
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;
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'