root/ext/intl/dateformat/dateformat_parse.c

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

DEFINITIONS

This source file includes following definitions.
  1. internal_parse_to_timestamp
  2. add_to_localtime_arr
  3. internal_parse_to_localtime
  4. PHP_FUNCTION
  5. 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 <math.h>
  23 
  24 #include "php_intl.h"
  25 #include "intl_convert.h"
  26 #include "dateformat.h"
  27 #include "dateformat_class.h"
  28 #include "dateformat_parse.h"
  29 #include "dateformat_data.h"
  30 
  31 /* {{{
  32  * Internal function which calls the udat_parse
  33  * param int store_error acts like a boolean
  34  *      if set to 1 - store any error encountered  in the parameter parse_error
  35  *      if set to 0 - no need to store any error encountered  in the parameter parse_error
  36 */
  37 static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, zval *return_value)
  38 {
  39         double  result =  0;
  40         UDate   timestamp   =0;
  41         UChar*  text_utf16  = NULL;
  42         int32_t text_utf16_len = 0;
  43 
  44         /* Convert timezone to UTF-16. */
  45         intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo));
  46         INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" );
  47 
  48         timestamp = udat_parse( DATE_FORMAT_OBJECT(dfo), text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo));
  49         if( text_utf16 ){
  50                 efree(text_utf16);
  51         }
  52 
  53         INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" );
  54 
  55         /* Since return is in  sec. */
  56         result = (double)timestamp / U_MILLIS_PER_SECOND;
  57         if(result > LONG_MAX || result < -LONG_MAX) {
  58                 ZVAL_DOUBLE(return_value, result<0?ceil(result):floor(result));
  59         } else {
  60                 ZVAL_LONG(return_value, (zend_long)result);
  61         }
  62 }
  63 /* }}} */
  64 
  65 static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, const UCalendar *parsed_calendar, zend_long calendar_field, char* key_name)
  66 {
  67         zend_long calendar_field_val = ucal_get( parsed_calendar, calendar_field, &INTL_DATA_ERROR_CODE(dfo));
  68         INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : could not get a field from calendar" );
  69 
  70         if( strcmp(key_name, CALENDAR_YEAR )==0 ){
  71                 /* since tm_year is years from 1900 */
  72                 add_assoc_long( return_value, key_name,( calendar_field_val-1900) );
  73         }else if( strcmp(key_name, CALENDAR_WDAY )==0 ){
  74                 /* since tm_wday starts from 0 whereas ICU WDAY start from 1 */
  75                 add_assoc_long( return_value, key_name,( calendar_field_val-1) );
  76         }else{
  77                 add_assoc_long( return_value, key_name, calendar_field_val );
  78         }
  79 }
  80 
  81 /* {{{
  82  * Internal function which calls the udat_parseCalendar
  83 */
  84 static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, zval *return_value)
  85 {
  86         UCalendar      *parsed_calendar = NULL;
  87         UChar*          text_utf16  = NULL;
  88         int32_t         text_utf16_len = 0;
  89         zend_long               isInDST = 0;
  90 
  91         /* Convert timezone to UTF-16. */
  92         intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo));
  93         INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" );
  94 
  95         parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo));
  96         udat_parseCalendar( DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo));
  97 
  98         if (text_utf16) {
  99                 efree(text_utf16);
 100         }
 101 
 102         INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" );
 103 
 104 
 105         array_init( return_value );
 106         /* Add  entries from various fields of the obtained parsed_calendar */
 107         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_SECOND, CALENDAR_SEC);
 108         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MINUTE, CALENDAR_MIN);
 109         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_HOUR_OF_DAY, CALENDAR_HOUR);
 110         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_YEAR, CALENDAR_YEAR);
 111         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_MONTH, CALENDAR_MDAY);
 112         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_WEEK, CALENDAR_WDAY);
 113         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_YEAR, CALENDAR_YDAY);
 114         add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MONTH, CALENDAR_MON);
 115 
 116         /* Is in DST? */
 117         isInDST = ucal_inDaylightTime(parsed_calendar   , &INTL_DATA_ERROR_CODE(dfo));
 118         INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : while checking if currently in DST." );
 119         add_assoc_long( return_value, CALENDAR_ISDST,(isInDST==1?1:0));
 120 }
 121 /* }}} */
 122 
 123 
 124 /* {{{ proto integer IntlDateFormatter::parse( string $text_to_parse  [, int $parse_pos] )
 125  * Parse the string $value starting at parse_pos to a Unix timestamp -int }}}*/
 126 /* {{{ proto integer datefmt_parse( IntlDateFormatter $fmt, string $text_to_parse [, int $parse_pos] )
 127  * Parse the string $value starting at parse_pos to a Unix timestamp -int }}}*/
 128 PHP_FUNCTION(datefmt_parse)
 129 {
 130         char*           text_to_parse = NULL;
 131         size_t          text_len =0;
 132         zval*           z_parse_pos = NULL;
 133         int32_t                 parse_pos = -1;
 134 
 135         DATE_FORMAT_METHOD_INIT_VARS;
 136 
 137         /* Parse parameters. */
 138         if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|z/!",
 139                 &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){
 140                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_parse: unable to parse input params", 0 );
 141                 RETURN_FALSE;
 142         }
 143 
 144         /* Fetch the object. */
 145         DATE_FORMAT_METHOD_FETCH_OBJECT;
 146 
 147         if (z_parse_pos) {
 148                 ZVAL_DEREF(z_parse_pos);
 149                 convert_to_long(z_parse_pos);
 150                 parse_pos = (int32_t)Z_LVAL_P(z_parse_pos);
 151                 if(parse_pos > text_len) {
 152                         RETURN_FALSE;
 153                 }
 154         }
 155         internal_parse_to_timestamp( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value);
 156         if(z_parse_pos) {
 157                 zval_dtor(z_parse_pos);
 158                 ZVAL_LONG(z_parse_pos, parse_pos);
 159         }
 160 }
 161 /* }}} */
 162 
 163 /* {{{ proto integer IntlDateFormatter::localtime( string $text_to_parse[, int $parse_pos] )
 164  * Parse the string $value to a localtime array  }}}*/
 165 /* {{{ proto integer datefmt_localtime( IntlDateFormatter $fmt, string $text_to_parse[, int $parse_pos ])
 166  * Parse the string $value to a localtime array  }}}*/
 167 PHP_FUNCTION(datefmt_localtime)
 168 {
 169         char*           text_to_parse = NULL;
 170         size_t          text_len =0;
 171         zval*           z_parse_pos = NULL;
 172         int32_t         parse_pos = -1;
 173 
 174         DATE_FORMAT_METHOD_INIT_VARS;
 175 
 176         /* Parse parameters. */
 177         if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|z!",
 178                 &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){
 179                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_parse_to_localtime: unable to parse input params", 0 );
 180                 RETURN_FALSE;
 181         }
 182 
 183     /* Fetch the object. */
 184         DATE_FORMAT_METHOD_FETCH_OBJECT;
 185 
 186         if (z_parse_pos) {
 187                 ZVAL_DEREF(z_parse_pos);
 188                 convert_to_long(z_parse_pos);
 189                 parse_pos = (int32_t)Z_LVAL_P(z_parse_pos);
 190                 if(parse_pos > text_len) {
 191                         RETURN_FALSE;
 192                 }
 193         }
 194         internal_parse_to_localtime( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value);
 195         if (z_parse_pos) {
 196                 zval_dtor(z_parse_pos);
 197                 ZVAL_LONG(z_parse_pos, parse_pos);
 198         }
 199 }
 200 /* }}} */
 201 

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