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 7                                                        |
   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)
  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)
  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 ((ele_value = zend_hash_str_find(hash_arr, key_name, strlen(key_name))) != NULL) {
  74                 if(Z_TYPE_P(ele_value) != IS_LONG) {
  75                         spprintf(&message, 0, "datefmt_format: parameter array contains "
  76                                         "a non-integer element for key '%s'", key_name);
  77                         intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
  78                         efree(message);
  79                 } else {
  80                         if (Z_LVAL_P(ele_value) > INT32_MAX ||
  81                                         Z_LVAL_P(ele_value) < INT32_MIN) {
  82                                 spprintf(&message, 0, "datefmt_format: value %pd is out of "
  83                                                 "bounds for a 32-bit integer in key '%s'",
  84                                                 Z_LVAL_P(ele_value), key_name);
  85                                 intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
  86                                 efree(message);
  87                         } else {
  88                                 result = Z_LVAL_P(ele_value);
  89                         }
  90                 }
  91         }
  92 
  93         return result;
  94 }
  95 /* }}} */
  96 
  97 /* {{{
  98  * Internal function which sets UCalendar  from the passed array and retrieves timestamp
  99 */
 100 static UDate internal_get_timestamp(IntlDateFormatter_object *dfo,
 101                 HashTable *hash_arr)
 102 {
 103         int32_t         year,
 104                                 month,
 105                                 hour,
 106                                 minute,
 107                                 second,
 108                                 mday;
 109         UCalendar       *pcal;
 110         UDate           result;
 111         intl_error      *err = &dfo->datef_data.error;
 112 
 113 #define INTL_GET_ELEM(elem) \
 114         internal_get_arr_ele(dfo, hash_arr, (elem), err)
 115 
 116         /* Fetch  values from the incoming array */
 117         year    = INTL_GET_ELEM(CALENDAR_YEAR) + 1900; /* tm_year is years since 1900 */
 118         /* Month in ICU and PHP starts from January =0 */
 119         month   = INTL_GET_ELEM(CALENDAR_MON);
 120         hour    = INTL_GET_ELEM(CALENDAR_HOUR);
 121         minute  = INTL_GET_ELEM(CALENDAR_MIN);
 122         second  = INTL_GET_ELEM(CALENDAR_SEC);
 123         /* For the ucal_setDateTime() function, this is the 'date'  value */
 124         mday    = INTL_GET_ELEM(CALENDAR_MDAY);
 125 
 126 #undef INTL_GET_ELEM
 127 
 128         pcal = ucal_clone(udat_getCalendar(DATE_FORMAT_OBJECT(dfo)),
 129                         &INTL_DATA_ERROR_CODE(dfo));
 130 
 131         if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) {
 132                 intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "datefmt_format: "
 133                                 "error cloning calendar", 0);
 134                 return 0;
 135         }
 136 
 137         /* set the incoming values for the calendar */
 138         ucal_setDateTime(pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo));
 139         /* actually, ucal_setDateTime cannot fail */
 140 
 141         /* Fetch the timestamp from the UCalendar */
 142         result = ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo));
 143         ucal_close(pcal);
 144         return result;
 145 }
 146 
 147 
 148 /* {{{ proto string IntlDateFormatter::format( [mixed]int $args or array $args )
 149  * Format the time value as a string. }}}*/
 150 /* {{{ proto string datefmt_format( [mixed]int $args or array $args )
 151  * Format the time value as a string. }}}*/
 152 PHP_FUNCTION(datefmt_format)
 153 {
 154         UDate           timestamp       = 0;
 155         HashTable       *hash_arr       = NULL;
 156         zval            *zarg           = NULL;
 157 
 158         DATE_FORMAT_METHOD_INIT_VARS;
 159 
 160         /* Parse parameters. */
 161         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz",
 162                         &object, IntlDateFormatter_ce_ptr, &zarg) == FAILURE) {
 163                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable "
 164                                 "to parse input params", 0 );
 165                 RETURN_FALSE;
 166         }
 167 
 168         DATE_FORMAT_METHOD_FETCH_OBJECT;
 169 
 170         if (Z_TYPE_P(zarg) == IS_ARRAY) {
 171                 hash_arr = Z_ARRVAL_P(zarg);
 172                 if (!hash_arr || zend_hash_num_elements(hash_arr) == 0) {
 173                         RETURN_FALSE;
 174                 }
 175 
 176                 timestamp = internal_get_timestamp(dfo, hash_arr);
 177                 INTL_METHOD_CHECK_STATUS(dfo, "datefmt_format: date formatting failed")
 178         } else {
 179                 timestamp = intl_zval_to_millis(zarg, INTL_DATA_ERROR_P(dfo),
 180                                 "datefmt_format");
 181                 if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
 182                         RETURN_FALSE;
 183                 }
 184         }
 185 
 186         internal_format( dfo, timestamp, return_value);
 187 }
 188 
 189 /* }}} */
 190 

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