root/ext/intl/dateformat/dateformat_format.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. internal_format
  2. internal_get_arr_ele
  3. internal_get_timestamp
  4. PHP_FUNCTION

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | This source file is subject to version 3.01 of the PHP license,      |
   6    | that is bundled with this package in the file LICENSE, and is        |
   7    | available through the world-wide-web at the following url:           |
   8    | http://www.php.net/license/3_01.txt                                  |
   9    | If you did not receive a copy of the PHP license and are unable to   |
  10    | obtain it through the world-wide-web, please send a note to          |
  11    | license@php.net so we can mail you a copy immediately.               |
  12    +----------------------------------------------------------------------+
  13    | Authors: Kirti Velankar <kirtig@yahoo-inc.com>                       |
  14    +----------------------------------------------------------------------+
  15 */
  16 
  17 #ifdef HAVE_CONFIG_H
  18 #include "config.h"
  19 #endif
  20 
  21 #include <unicode/ustring.h>
  22 #include <unicode/ucal.h>
  23 
  24 #include "../php_intl.h"
  25 #include "../intl_convert.h"
  26 #include "../common/common_date.h"
  27 #include "dateformat.h"
  28 #include "dateformat_class.h"
  29 #include "dateformat_format.h"
  30 #include "dateformat_data.h"
  31 
  32 /* {{{ 
  33  * Internal function which calls the udat_format
  34 */
  35 static void internal_format(IntlDateFormatter_object *dfo, UDate timestamp, zval *return_value TSRMLS_DC)
  36 {
  37         UChar*  formatted =  NULL;
  38         int32_t resultlengthneeded =0 ;
  39         
  40         resultlengthneeded=udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, NULL, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo));
  41         if(INTL_DATA_ERROR_CODE(dfo)==U_BUFFER_OVERFLOW_ERROR)
  42         {
  43                 INTL_DATA_ERROR_CODE(dfo)=U_ZERO_ERROR;
  44                 formatted=(UChar*)emalloc(sizeof(UChar) * resultlengthneeded); 
  45                 udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, formatted, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo));
  46         }
  47 
  48         if (formatted && U_FAILURE( INTL_DATA_ERROR_CODE(dfo) ) ) {
  49                         efree(formatted);
  50         }
  51 
  52         INTL_METHOD_CHECK_STATUS( dfo, "Date formatting failed" );
  53         INTL_METHOD_RETVAL_UTF8( dfo, formatted, resultlengthneeded, 1 );
  54 
  55 }
  56 /* }}} */
  57 
  58 
  59 /* {{{ 
  60  * Internal function which fetches an element from the passed array for the key_name passed 
  61 */
  62 static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo,
  63                 HashTable* hash_arr, char* key_name, intl_error *err TSRMLS_DC)
  64 {
  65         zval    **ele_value     = NULL;
  66         int32_t result          = 0;
  67         char    *message;
  68 
  69         if (U_FAILURE(err->code)) {
  70                 return result;
  71         }
  72 
  73         if (zend_hash_find(hash_arr, key_name, strlen(key_name) + 1,
  74                         (void **)&ele_value) == SUCCESS) {
  75                 if(Z_TYPE_PP(ele_value) != IS_LONG) {
  76                         spprintf(&message, 0, "datefmt_format: parameter array contains "
  77                                         "a non-integer element for key '%s'", key_name);
  78                         intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
  79                         efree(message);
  80                 } else {
  81                         if (Z_LVAL_PP(ele_value) > INT32_MAX ||
  82                                         Z_LVAL_PP(ele_value) < INT32_MIN) {
  83                                 spprintf(&message, 0, "datefmt_format: value %ld is out of "
  84                                                 "bounds for a 32-bit integer in key '%s'",
  85                                                 Z_LVAL_PP(ele_value), key_name);
  86                                 intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
  87                                 efree(message);
  88                         } else {
  89                                 result = Z_LVAL_PP(ele_value);
  90                         }
  91                 }
  92         }
  93 
  94         return result;
  95 }
  96 /* }}} */
  97 
  98 /* {{{ 
  99  * Internal function which sets UCalendar  from the passed array and retrieves timestamp
 100 */
 101 static UDate internal_get_timestamp(IntlDateFormatter_object *dfo,
 102                 HashTable *hash_arr TSRMLS_DC)
 103 {
 104         int32_t         year,
 105                                 month,
 106                                 hour,
 107                                 minute,
 108                                 second,
 109                                 mday;
 110         UCalendar       *pcal;
 111         UDate           result;
 112         intl_error      *err = &dfo->datef_data.error;
 113 
 114 #define INTL_GET_ELEM(elem) \
 115         internal_get_arr_ele(dfo, hash_arr, (elem), err TSRMLS_CC)
 116 
 117         /* Fetch  values from the incoming array */
 118         year    = INTL_GET_ELEM(CALENDAR_YEAR) + 1900; /* tm_year is years since 1900 */
 119         /* Month in ICU and PHP starts from January =0 */
 120         month   = INTL_GET_ELEM(CALENDAR_MON);
 121         hour    = INTL_GET_ELEM(CALENDAR_HOUR);
 122         minute  = INTL_GET_ELEM(CALENDAR_MIN);
 123         second  = INTL_GET_ELEM(CALENDAR_SEC);
 124         /* For the ucal_setDateTime() function, this is the 'date'  value */
 125         mday    = INTL_GET_ELEM(CALENDAR_MDAY);
 126 
 127 #undef INTL_GET_ELEM
 128 
 129         pcal = ucal_clone(udat_getCalendar(DATE_FORMAT_OBJECT(dfo)),
 130                         &INTL_DATA_ERROR_CODE(dfo));
 131 
 132         if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) {
 133                 intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "datefmt_format: "
 134                                 "error cloning calendar", 0 TSRMLS_CC);
 135                 return 0;
 136         }
 137 
 138         /* set the incoming values for the calendar */
 139         ucal_setDateTime(pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo));
 140         /* actually, ucal_setDateTime cannot fail */
 141 
 142         /* Fetch the timestamp from the UCalendar */
 143         result = ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo));
 144         ucal_close(pcal);
 145         return result;
 146 }
 147 
 148 
 149 /* {{{ proto string IntlDateFormatter::format( [mixed]int $args or array $args )
 150  * Format the time value as a string. }}}*/
 151 /* {{{ proto string datefmt_format( [mixed]int $args or array $args )
 152  * Format the time value as a string. }}}*/
 153 PHP_FUNCTION(datefmt_format) 
 154 {
 155         UDate           timestamp       = 0;
 156         HashTable       *hash_arr       = NULL;
 157         zval            *zarg           = NULL;
 158 
 159         DATE_FORMAT_METHOD_INIT_VARS;
 160 
 161         /* Parse parameters. */
 162         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz",
 163                         &object, IntlDateFormatter_ce_ptr, &zarg) == FAILURE) {
 164                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable "
 165                                 "to parse input params", 0 TSRMLS_CC );
 166                 RETURN_FALSE;
 167         }
 168 
 169         DATE_FORMAT_METHOD_FETCH_OBJECT;
 170 
 171         if (Z_TYPE_P(zarg) == IS_ARRAY) {
 172                 hash_arr = Z_ARRVAL_P(zarg);
 173                 if (!hash_arr || zend_hash_num_elements(hash_arr) == 0) {
 174                         RETURN_FALSE;
 175                 }
 176 
 177                 timestamp = internal_get_timestamp(dfo, hash_arr TSRMLS_CC);
 178                 INTL_METHOD_CHECK_STATUS(dfo, "datefmt_format: date formatting failed")
 179         } else {
 180                 timestamp = intl_zval_to_millis(zarg, INTL_DATA_ERROR_P(dfo),
 181                                 "datefmt_format" TSRMLS_CC);
 182                 if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
 183                         RETURN_FALSE;
 184                 }
 185         }
 186         
 187         internal_format( dfo, timestamp, return_value TSRMLS_CC);
 188 }
 189 
 190 /* }}} */
 191 

/* [<][>][^][v][top][bottom][index][help] */