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 "dateformat.h"
27 : #include "dateformat_class.h"
28 : #include "dateformat_format.h"
29 : #include "dateformat_data.h"
30 :
31 : /* {{{
32 : * Internal function which calls the udat_format
33 : */
34 : static void internal_format(IntlDateFormatter_object *dfo, UDate timestamp, zval *return_value TSRMLS_DC)
35 202 : {
36 202 : UChar* formatted = NULL;
37 202 : int32_t resultlengthneeded =0 ;
38 :
39 202 : resultlengthneeded=udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, NULL, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo));
40 202 : if(INTL_DATA_ERROR_CODE(dfo)==U_BUFFER_OVERFLOW_ERROR)
41 : {
42 202 : INTL_DATA_ERROR_CODE(dfo)=U_ZERO_ERROR;
43 202 : formatted=(UChar*)emalloc(sizeof(UChar) * resultlengthneeded);
44 202 : udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, formatted, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo));
45 : }
46 :
47 202 : if (formatted && U_FAILURE( INTL_DATA_ERROR_CODE(dfo) ) ) {
48 0 : efree(formatted);
49 : }
50 :
51 202 : INTL_METHOD_CHECK_STATUS( dfo, "Date formatting failed" );
52 202 : INTL_METHOD_RETVAL_UTF8( dfo, formatted, resultlengthneeded, 1 );
53 :
54 : }
55 : /* }}} */
56 :
57 :
58 : /* {{{
59 : * Internal function which fetches an element from the passed array for the key_name passed
60 : */
61 : static double internal_get_arr_ele(IntlDateFormatter_object *dfo, HashTable* hash_arr, char* key_name TSRMLS_DC)
62 432 : {
63 432 : zval** ele_value = NULL;
64 432 : UDate result = -1;
65 :
66 432 : if( zend_hash_find( hash_arr, key_name, strlen(key_name) + 1, (void **)&ele_value ) == SUCCESS ){
67 288 : if( Z_TYPE_PP(ele_value)!= IS_LONG ){
68 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
69 : "datefmt_format: parameter array does not contain a long element.", 0 TSRMLS_CC );
70 : }else{
71 288 : result = Z_LVAL_PP(ele_value);
72 : }
73 : }
74 : /* printf("\n Inside internal_get_arr_ele key_name= %s, result = %g \n", key_name, result); */
75 432 : return result;
76 : }
77 : /* }}} */
78 :
79 : /* {{{
80 : * Internal function which sets UCalendar from the passed array and retrieves timestamp
81 : */
82 : static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, HashTable* hash_arr TSRMLS_DC)
83 48 : {
84 48 : long year =0;
85 48 : long month =0;
86 48 : long hour =0;
87 48 : long minute =0;
88 48 : long second =0;
89 48 : long wday =0;
90 48 : long yday =0;
91 48 : long mday =0;
92 48 : UBool isInDST = FALSE;
93 : UCalendar *pcal;
94 :
95 : /* Fetch values from the incoming array */
96 48 : year = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YEAR TSRMLS_CC) + 1900; /* tm_year is years since 1900 */
97 : /* Month in ICU and PHP starts from January =0 */
98 48 : month = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MON TSRMLS_CC);
99 48 : hour = internal_get_arr_ele( dfo, hash_arr, CALENDAR_HOUR TSRMLS_CC);
100 48 : minute = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MIN TSRMLS_CC);
101 48 : second = internal_get_arr_ele( dfo, hash_arr, CALENDAR_SEC TSRMLS_CC);
102 48 : wday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_WDAY TSRMLS_CC);
103 48 : yday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YDAY TSRMLS_CC);
104 48 : isInDST = internal_get_arr_ele( dfo, hash_arr, CALENDAR_ISDST TSRMLS_CC);
105 : /* For the ucal_setDateTime() function, this is the 'date' value */
106 48 : mday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MDAY TSRMLS_CC);
107 :
108 48 : pcal = udat_getCalendar(DATE_FORMAT_OBJECT(dfo));
109 : /* set the incoming values for the calendar */
110 48 : ucal_setDateTime( pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo));
111 48 : if( INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR){
112 0 : return 0;
113 : }
114 :
115 : /* Fetch the timestamp from the UCalendar */
116 48 : return ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo) );
117 : }
118 :
119 :
120 : /* {{{ proto string IntlDateFormatter::format( [mixed]int $args or array $args )
121 : * Format the time value as a string. }}}*/
122 : /* {{{ proto string datefmt_format( [mixed]int $args or array $args )
123 : * Format the time value as a string. }}}*/
124 : PHP_FUNCTION(datefmt_format)
125 202 : {
126 202 : UDate timestamp =0;
127 202 : UDate p_timestamp =0;
128 202 : HashTable* hash_arr = NULL;
129 202 : zval* zarg = NULL;
130 :
131 202 : DATE_FORMAT_METHOD_INIT_VARS;
132 :
133 : /* Parse parameters. */
134 202 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &object, IntlDateFormatter_ce_ptr,&zarg ) == FAILURE )
135 : {
136 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable to parse input params", 0 TSRMLS_CC );
137 0 : RETURN_FALSE;
138 : }
139 :
140 : /* Fetch the object. */
141 202 : DATE_FORMAT_METHOD_FETCH_OBJECT;
142 :
143 202 : switch(Z_TYPE_P(zarg) ){
144 : case IS_LONG:
145 122 : p_timestamp = Z_LVAL_P(zarg) ;
146 122 : timestamp = p_timestamp * 1000;
147 122 : break;
148 : case IS_DOUBLE:
149 : /* timestamp*1000 since ICU expects it in milliseconds */
150 32 : p_timestamp = Z_DVAL_P(zarg) ;
151 32 : timestamp = p_timestamp * 1000;
152 32 : break;
153 : case IS_ARRAY:
154 48 : hash_arr = Z_ARRVAL_P(zarg);
155 48 : if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 )
156 0 : RETURN_FALSE;
157 :
158 48 : timestamp = internal_get_timestamp(dfo, hash_arr TSRMLS_CC);
159 48 : INTL_METHOD_CHECK_STATUS( dfo, "datefmt_format: Date formatting failed" )
160 48 : break;
161 : default:
162 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
163 : "datefmt_format: takes either an array or an integer timestamp value ", 0 TSRMLS_CC );
164 0 : RETURN_FALSE;
165 : }
166 :
167 202 : internal_format( dfo, timestamp, return_value TSRMLS_CC);
168 :
169 : }
170 :
171 : /* }}} */
172 :
|