Back to index

php5  5.3.10
dateformat_parse.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | This source file is subject to version 3.01 of the PHP license,      |
00006    | that is bundled with this package in the file LICENSE, and is        |
00007    | available through the world-wide-web at the following url:           |
00008    | http://www.php.net/license/3_01.txt                                  |
00009    | If you did not receive a copy of the PHP license and are unable to   |
00010    | obtain it through the world-wide-web, please send a note to          |
00011    | license@php.net so we can mail you a copy immediately.               |
00012    +----------------------------------------------------------------------+
00013    | Authors: Kirti Velankar <kirtig@yahoo-inc.com>                       |
00014    +----------------------------------------------------------------------+
00015 */
00016 
00017 #ifdef HAVE_CONFIG_H
00018 #include "config.h"
00019 #endif
00020 
00021 #include <unicode/ustring.h>
00022 #include <math.h>
00023 
00024 #include "php_intl.h"
00025 #include "intl_convert.h"
00026 #include "dateformat.h"
00027 #include "dateformat_class.h"
00028 #include "dateformat_parse.h"
00029 #include "dateformat_data.h"
00030 
00031 /* {{{ 
00032  * Internal function which calls the udat_parse
00033  * param int store_error acts like a boolean 
00034  *     if set to 1 - store any error encountered  in the parameter parse_error  
00035  *     if set to 0 - no need to store any error encountered  in the parameter parse_error  
00036 */
00037 static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* text_to_parse, int32_t text_len, int32_t *parse_pos, zval *return_value TSRMLS_DC)
00038 {
00039        double result =  0;
00040        UDate  timestamp   =0;
00041        UChar*        text_utf16  = NULL;
00042        int32_t text_utf16_len = 0;
00043 
00044        /* Convert timezone to UTF-16. */
00045        intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo));
00046        INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" );
00047 
00048        timestamp = udat_parse( DATE_FORMAT_OBJECT(dfo), text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo));
00049        if( text_utf16 ){
00050               efree(text_utf16);
00051        }
00052 
00053        INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" );
00054        
00055        /* Since return is in  sec. */
00056        result = (double)timestamp / U_MILLIS_PER_SECOND;
00057        if(result > LONG_MAX || result < -LONG_MAX) {
00058               ZVAL_DOUBLE(return_value, result<0?ceil(result):floor(result));
00059        } else {
00060               ZVAL_LONG(return_value, (long)result);
00061        }
00062 }
00063 /* }}} */
00064 
00065 static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, UCalendar parsed_calendar, long calendar_field, char* key_name TSRMLS_DC)
00066 {
00067        long calendar_field_val = ucal_get( parsed_calendar, calendar_field, &INTL_DATA_ERROR_CODE(dfo)); 
00068        INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : could not get a field from calendar" );
00069 
00070        if( strcmp(key_name, CALENDAR_YEAR )==0 ){
00071               /* since tm_year is years from 1900 */
00072               add_assoc_long( return_value, key_name,( calendar_field_val-1900) ); 
00073        }else if( strcmp(key_name, CALENDAR_WDAY )==0 ){
00074               /* since tm_wday starts from 0 whereas ICU WDAY start from 1 */
00075               add_assoc_long( return_value, key_name,( calendar_field_val-1) ); 
00076        }else{
00077               add_assoc_long( return_value, key_name, calendar_field_val ); 
00078        }
00079 }
00080 
00081 /* {{{
00082  * Internal function which calls the udat_parseCalendar
00083 */
00084 static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, int32_t text_len, int32_t *parse_pos, zval *return_value TSRMLS_DC)
00085 {
00086        UCalendar*    parsed_calendar = NULL;
00087        UChar*        text_utf16  = NULL;
00088        int32_t       text_utf16_len = 0;
00089        long          isInDST = 0;
00090 
00091        /* Convert timezone to UTF-16. */
00092        intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo));
00093        INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" );
00094 
00095        parsed_calendar = udat_getCalendar(DATE_FORMAT_OBJECT(dfo));
00096        udat_parseCalendar( DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo));
00097        
00098        if (text_utf16) {
00099               efree(text_utf16);
00100        }
00101 
00102        INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" );
00103 
00104 
00105        array_init( return_value );
00106        /* Add  entries from various fields of the obtained parsed_calendar */
00107        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_SECOND, CALENDAR_SEC TSRMLS_CC);
00108        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MINUTE, CALENDAR_MIN TSRMLS_CC);
00109        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_HOUR_OF_DAY, CALENDAR_HOUR TSRMLS_CC);
00110        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_YEAR, CALENDAR_YEAR TSRMLS_CC); 
00111        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_MONTH, CALENDAR_MDAY TSRMLS_CC);
00112        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_WEEK, CALENDAR_WDAY TSRMLS_CC);
00113        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_YEAR, CALENDAR_YDAY TSRMLS_CC);
00114        add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MONTH, CALENDAR_MON TSRMLS_CC);
00115 
00116        /* Is in DST? */
00117        isInDST = ucal_inDaylightTime(parsed_calendar    , &INTL_DATA_ERROR_CODE(dfo));
00118        INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : while checking if currently in DST." );
00119        add_assoc_long( return_value, CALENDAR_ISDST,(isInDST==1?1:0)); 
00120 }
00121 /* }}} */
00122 
00123 
00124 /* {{{ proto integer IntlDateFormatter::parse( string $text_to_parse  [, int $parse_pos] )
00125  * Parse the string $value starting at parse_pos to a Unix timestamp -int }}}*/
00126 /* {{{ proto integer datefmt_parse( IntlDateFormatter $fmt, string $text_to_parse [, int $parse_pos] )
00127  * Parse the string $value starting at parse_pos to a Unix timestamp -int }}}*/
00128 PHP_FUNCTION(datefmt_parse)
00129 {
00130        char*           text_to_parse = NULL;
00131        int32_t         text_len =0;
00132        zval*                z_parse_pos = NULL;
00133        int32_t                     parse_pos = -1;
00134 
00135        DATE_FORMAT_METHOD_INIT_VARS;
00136 
00137        /* Parse parameters. */
00138        if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|z!",
00139               &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){
00140               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_parse: unable to parse input params", 0 TSRMLS_CC );
00141               RETURN_FALSE;
00142        }
00143 
00144        /* Fetch the object. */
00145        DATE_FORMAT_METHOD_FETCH_OBJECT;
00146 
00147        if (z_parse_pos) {
00148               convert_to_long(z_parse_pos);
00149               parse_pos = (int32_t)Z_LVAL_P(z_parse_pos);
00150               if(parse_pos > text_len) {
00151                      RETURN_FALSE;
00152               }
00153        }
00154        internal_parse_to_timestamp( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value TSRMLS_CC);
00155        if(z_parse_pos) {
00156               zval_dtor(z_parse_pos);
00157               ZVAL_LONG(z_parse_pos, parse_pos);
00158        }
00159 }
00160 /* }}} */
00161 
00162 /* {{{ proto integer IntlDateFormatter::localtime( string $text_to_parse[, int $parse_pos] )
00163  * Parse the string $value to a localtime array  }}}*/
00164 /* {{{ proto integer datefmt_localtime( IntlDateFormatter $fmt, string $text_to_parse[, int $parse_pos ])
00165  * Parse the string $value to a localtime array  }}}*/
00166 PHP_FUNCTION(datefmt_localtime)
00167 {
00168        char*           text_to_parse = NULL;
00169        int32_t         text_len =0;
00170        zval*                z_parse_pos = NULL;
00171        int32_t                     parse_pos = -1;
00172 
00173        DATE_FORMAT_METHOD_INIT_VARS;
00174 
00175        /* Parse parameters. */
00176        if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|z!",
00177               &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){
00178               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_parse_to_localtime: unable to parse input params", 0 TSRMLS_CC );
00179               RETURN_FALSE;
00180        }
00181 
00182     /* Fetch the object. */
00183        DATE_FORMAT_METHOD_FETCH_OBJECT;
00184 
00185        if(z_parse_pos) {
00186               convert_to_long(z_parse_pos);
00187               parse_pos = (int32_t)Z_LVAL_P(z_parse_pos);
00188               if(parse_pos > text_len) {
00189                      RETURN_FALSE;
00190               }
00191        }
00192        internal_parse_to_localtime( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value TSRMLS_CC);
00193        if(z_parse_pos) {
00194               zval_dtor(z_parse_pos);
00195               ZVAL_LONG(z_parse_pos, parse_pos);
00196        }
00197 }
00198 /* }}} */
00199