]> granicus.if.org Git - php/commitdiff
Unified zval -> UDate conversions
authorGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 1 Jul 2012 22:24:54 +0000 (00:24 +0200)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 1 Jul 2012 22:24:54 +0000 (00:24 +0200)
Now IntlDateFormatter::format() also accepts IntlCalendar objects.
Code is shared in MessageFormatter and IntlDateFormatter.

ext/intl/common/common_date.cpp [new file with mode: 0644]
ext/intl/common/common_date.h [new file with mode: 0644]
ext/intl/config.m4
ext/intl/config.w32
ext/intl/dateformat/dateformat.h
ext/intl/dateformat/dateformat_format.c
ext/intl/msgformat/msgformat_helpers.cpp
ext/intl/tests/dateformat_format.phpt

diff --git a/ext/intl/common/common_date.cpp b/ext/intl/common/common_date.cpp
new file mode 100644 (file)
index 0000000..812a196
--- /dev/null
@@ -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;
+}
+
diff --git a/ext/intl/common/common_date.h b/ext/intl/common/common_date.h
new file mode 100644 (file)
index 0000000..cfa14d1
--- /dev/null
@@ -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 */
+
index 431deeb7d290681e08f6c0944a98b3cb89271f56..8598161e2b88751ea0544ac104e9b9666cfcfe8e 100755 (executable)
@@ -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 \
index 735749ab438d9fe2ae065713be4e3e0da4dabd52..d57c7f3a334e907a6acd44e8362c899547226933 100755 (executable)
@@ -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 \
index f11918b79f142d5f17368c1d9d58ba1b04733098..a5a747328f7b7d4e7c9b89580d36233f2a021d8a 100755 (executable)
@@ -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
index 82f825f140386a76517f5afc20ecf538065bede0..65fe68eaf5df470b7edac2da5c72d96e7209ec55 100755 (executable)
 #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);
 }
 
 /* }}} */
index fd8df1a39c3018e106991c95841c0c8a9c5dc98e..c8223190784a09255cfdb627defe739c3a538b6b 100755 (executable)
@@ -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;
index 98f9d34c03ab95fa87c1c0e0c4f878071e71484a..d09de0e439614db84e58d8f5c446b6a85249b30b 100755 (executable)
@@ -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'