]> granicus.if.org Git - php/commitdiff
- MFH: Added support for using ISO 8601 time intervals to define a DatePeriod
authorDerick Rethans <derick@php.net>
Sun, 4 May 2008 10:00:01 +0000 (10:00 +0000)
committerDerick Rethans <derick@php.net>
Sun, 4 May 2008 10:00:01 +0000 (10:00 +0000)
  iterator.
#- @doc

ext/date/lib/parse_iso_intervals.c
ext/date/lib/parse_iso_intervals.re
ext/date/php_date.c

index 0a1aa5ddb0742950e828bbe5989a306f58c6f563..e327237a375531d5d474e13ada561e2e3d0b07e6 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.3 on Sun Apr 27 20:57:09 2008 */
+/* Generated by re2c 0.13.4 on Sat May  3 13:59:42 2008 */
 #line 1 "ext/date/lib/parse_iso_intervals.re"
 /*
    +----------------------------------------------------------------------+
@@ -325,10 +325,10 @@ std:
        if ((YYLIMIT - YYCURSOR) < 20) YYFILL(20);
        yych = *YYCURSOR;
        if (yych <= ',') {
-               if (yych <= 0x0A) {
+               if (yych <= '\n') {
                        if (yych <= 0x00) goto yy9;
                        if (yych <= 0x08) goto yy11;
-                       if (yych <= 0x09) goto yy7;
+                       if (yych <= '\t') goto yy7;
                        goto yy9;
                } else {
                        if (yych == ' ') goto yy7;
@@ -527,7 +527,7 @@ yy21:
 yy23:
        YYDEBUG(23, *YYCURSOR);
        ++YYCURSOR;
-       if (YYLIMIT == YYCURSOR) YYFILL(1);
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        YYDEBUG(24, *YYCURSOR);
        if (yych <= '/') goto yy14;
@@ -830,7 +830,7 @@ yy69:
 yy74:
        YYDEBUG(74, *YYCURSOR);
        ++YYCURSOR;
-       if (YYLIMIT == YYCURSOR) YYFILL(1);
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        YYDEBUG(75, *YYCURSOR);
        if (yych <= '/') goto yy76;
@@ -905,11 +905,11 @@ void timelib_strtointerval(char *s, int len,
        in.begin->h = TIMELIB_UNSET;
        in.begin->i = TIMELIB_UNSET;
        in.begin->s = TIMELIB_UNSET;
-       in.begin->f = TIMELIB_UNSET;
-       in.begin->z = TIMELIB_UNSET;
-       in.begin->dst = TIMELIB_UNSET;
+       in.begin->f = 0;
+       in.begin->z = 0;
+       in.begin->dst = 0;
        in.begin->is_localtime = 0;
-       in.begin->zone_type = 0;
+       in.begin->zone_type = TIMELIB_ZONETYPE_OFFSET;
 
        in.end = timelib_time_ctor();
        in.end->y = TIMELIB_UNSET;
@@ -918,11 +918,11 @@ void timelib_strtointerval(char *s, int len,
        in.end->h = TIMELIB_UNSET;
        in.end->i = TIMELIB_UNSET;
        in.end->s = TIMELIB_UNSET;
-       in.end->f = TIMELIB_UNSET;
-       in.end->z = TIMELIB_UNSET;
-       in.end->dst = TIMELIB_UNSET;
+       in.end->f = 0;
+       in.end->z = 0;
+       in.end->dst = 0;
        in.end->is_localtime = 0;
-       in.end->zone_type = 0;
+       in.end->zone_type = TIMELIB_ZONETYPE_OFFSET;
 
        in.period = timelib_rel_time_ctor();
        in.period->y = 0;
index b34bba94be991d7a4fbc07c4fce0e03b217dd879..c712670558a07343d4950ecce53582991391a98e 100644 (file)
@@ -452,11 +452,11 @@ void timelib_strtointerval(char *s, int len,
        in.begin->h = TIMELIB_UNSET;
        in.begin->i = TIMELIB_UNSET;
        in.begin->s = TIMELIB_UNSET;
-       in.begin->f = TIMELIB_UNSET;
-       in.begin->z = TIMELIB_UNSET;
-       in.begin->dst = TIMELIB_UNSET;
+       in.begin->f = 0;
+       in.begin->z = 0;
+       in.begin->dst = 0;
        in.begin->is_localtime = 0;
-       in.begin->zone_type = 0;
+       in.begin->zone_type = TIMELIB_ZONETYPE_OFFSET;
 
        in.end = timelib_time_ctor();
        in.end->y = TIMELIB_UNSET;
@@ -465,11 +465,11 @@ void timelib_strtointerval(char *s, int len,
        in.end->h = TIMELIB_UNSET;
        in.end->i = TIMELIB_UNSET;
        in.end->s = TIMELIB_UNSET;
-       in.end->f = TIMELIB_UNSET;
-       in.end->z = TIMELIB_UNSET;
-       in.end->dst = TIMELIB_UNSET;
+       in.end->f = 0;
+       in.end->z = 0;
+       in.end->dst = 0;
        in.end->is_localtime = 0;
-       in.end->zone_type = 0;
+       in.end->zone_type = TIMELIB_ZONETYPE_OFFSET;
 
        in.period = timelib_rel_time_ctor();
        in.period->y = 0;
index 0b4c06efd2f44f70149a0b8c8e9ca0fcb17f71a1..a7cf8e5c2fc8e04d7cef65ca10b796048876a4a3 100644 (file)
@@ -3370,6 +3370,30 @@ PHP_FUNCTION(date_interval_format)
 }
 /* }}} */
 
+static int date_period_initialize(timelib_time **st, timelib_time **et, timelib_rel_time **d, int *recurrences, /*const*/ char *format, int format_length TSRMLS_DC)
+{
+       timelib_time     *b = NULL, *e = NULL;
+       timelib_rel_time *p = NULL;
+       int               r = 0;
+       int               retval = 0;
+       struct timelib_error_container *errors;
+
+       timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors);
+       
+       if (errors->error_count > 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad format (%s)", format);
+               retval = FAILURE;
+       } else {
+               *st = b;
+               *et = e;
+               *d  = p;
+               *recurrences = r;
+               retval = SUCCESS;
+       }
+       timelib_error_container_dtor(errors);
+       return retval;
+}
+
 /* {{{ proto DatePeriod::__construct(DateTime $start, DateInterval $interval, int recurrences|DateTime $end)
    Creates new DatePeriod object.
 */
@@ -3380,38 +3404,44 @@ PHP_METHOD(DatePeriod, __construct)
        php_interval_obj *intobj;
        zval *start, *end = NULL, *interval;
        long  recurrences = 0, options = 0;
+       char *isostr = NULL;
+       int   isostr_len;
        timelib_time *clone;
        
        php_set_error_handling(EH_THROW, NULL TSRMLS_CC);
        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_date, &interval, date_ce_interval, &recurrences, &options) == FAILURE) {
                if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_date, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) as arguments.");
-                       return;
+                       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) OR (string) as arguments.");
+                               return;
+                       }
                }
        }
 
-       /* init */
-       intobj  = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
        dpobj = zend_object_store_get_object(getThis() TSRMLS_CC);
 
-       /* start date */
-       dateobj = (php_date_obj *) zend_object_store_get_object(start TSRMLS_CC);
-       clone = timelib_time_ctor();
-       memcpy(clone, dateobj->time, sizeof(timelib_time));
-       if (dateobj->time->tz_abbr) {
-               clone->tz_abbr = strdup(dateobj->time->tz_abbr);
-       }
-       if (dateobj->time->tz_info) {
-               clone->tz_info = timelib_tzinfo_clone(dateobj->time->tz_info);
-       }
-       dpobj->start = clone;
+       if (isostr_len) {
+               date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), (int*) &recurrences, isostr, isostr_len TSRMLS_CC);
+               if (dpobj->start == NULL) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ISO interval '%s' did not contain a start date.", isostr);
+               }
+               if (dpobj->interval == NULL) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ISO interval '%s' did not contain an interval.", isostr);
+               }
+               if (dpobj->end == NULL && recurrences == 0) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ISO interval '%s' did not contain an end date or a recurrence count.", isostr);
+               }
 
-       /* interval */
-       dpobj->interval = timelib_rel_time_clone(intobj->diff);
+               timelib_update_ts(dpobj->start, NULL);
+               if (dpobj->end) {
+                       timelib_update_ts(dpobj->end, NULL);
+               }
+       } else {
+               /* init */
+               intobj  = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
 
-       /* end date */
-       if (end) {
-               dateobj = (php_date_obj *) zend_object_store_get_object(end TSRMLS_CC);
+               /* start date */
+               dateobj = (php_date_obj *) zend_object_store_get_object(start TSRMLS_CC);
                clone = timelib_time_ctor();
                memcpy(clone, dateobj->time, sizeof(timelib_time));
                if (dateobj->time->tz_abbr) {
@@ -3420,7 +3450,24 @@ PHP_METHOD(DatePeriod, __construct)
                if (dateobj->time->tz_info) {
                        clone->tz_info = timelib_tzinfo_clone(dateobj->time->tz_info);
                }
-               dpobj->end = clone;
+               dpobj->start = clone;
+
+               /* interval */
+               dpobj->interval = timelib_rel_time_clone(intobj->diff);
+
+               /* end date */
+               if (end) {
+                       dateobj = (php_date_obj *) zend_object_store_get_object(end TSRMLS_CC);
+                       clone = timelib_time_ctor();
+                       memcpy(clone, dateobj->time, sizeof(timelib_time));
+                       if (dateobj->time->tz_abbr) {
+                               clone->tz_abbr = strdup(dateobj->time->tz_abbr);
+                       }
+                       if (dateobj->time->tz_info) {
+                               clone->tz_info = timelib_tzinfo_clone(dateobj->time->tz_info);
+                       }
+                       dpobj->end = clone;
+               }
        }
 
        /* options */