diff --git a/ext/date/php_date.c b/ext/date/php_date.c index c604b936ba0..c16c8c8f483 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1451,16 +1451,6 @@ static int date_period_it_has_more(zend_object_iterator *iter) { date_period_it *iterator = (date_period_it *)iter; php_period_obj *object = Z_PHPPERIOD_P(&iterator->intern.data); - timelib_time *it_time = object->current; - - /* apply modification if it's not the first iteration */ - if (!object->include_start_date || iterator->current_index > 0) { - it_time->have_relative = 1; - it_time->relative = *object->interval; - it_time->sse_uptodate = 0; - timelib_update_ts(it_time, NULL); - timelib_update_from_sse(it_time); - } if (object->end) { return object->current->sse < object->end->sse ? SUCCESS : FAILURE; @@ -1502,10 +1492,23 @@ static void date_period_it_current_key(zend_object_iterator *iter, zval *key) } /* }}} */ +static void date_period_advance(timelib_time *it_time, timelib_rel_time *interval) +{ + it_time->have_relative = 1; + it_time->relative = *interval; + it_time->sse_uptodate = 0; + timelib_update_ts(it_time, NULL); + timelib_update_from_sse(it_time); +} + /* {{{ date_period_it_move_forward */ static void date_period_it_move_forward(zend_object_iterator *iter) { - date_period_it *iterator = (date_period_it *)iter; + date_period_it *iterator = (date_period_it *)iter; + php_period_obj *object = Z_PHPPERIOD_P(&iterator->intern.data); + timelib_time *it_time = object->current; + + date_period_advance(it_time, object->interval); iterator->current_index++; date_period_it_invalidate_current(iter); @@ -1525,7 +1528,13 @@ static void date_period_it_rewind(zend_object_iterator *iter) zend_throw_error(NULL, "DatePeriod has not been initialized correctly"); return; } + iterator->object->current = timelib_time_clone(iterator->object->start); + + if (!iterator->object->include_start_date) { + date_period_advance(iterator->object->current, iterator->object->interval); + } + date_period_it_invalidate_current(iter); } /* }}} */ diff --git a/ext/date/tests/DatePeriod_no_advance_on_valid.phpt b/ext/date/tests/DatePeriod_no_advance_on_valid.phpt new file mode 100644 index 00000000000..6a8a9d0f5d0 --- /dev/null +++ b/ext/date/tests/DatePeriod_no_advance_on_valid.phpt @@ -0,0 +1,52 @@ +--TEST-- +Date Period iterators do not advance on valid() +--FILE-- +getIterator(); + +foreach ($iterator as $item) { + echo $item->format('Y-m-d') . "\n"; +} + +echo "---------STEP 2\n"; + +foreach ($iterator as $item) { + $iterator->valid(); + echo $item->format('Y-m-d') . "\n"; +} + +$period = new DatePeriod($start, $interval, $end, DatePeriod::EXCLUDE_START_DATE); +$iterator = $period->getIterator(); + +echo "---------STEP 3\n"; + +foreach ($iterator as $item) { + echo $item->format('Y-m-d') . "\n"; +} + +echo "---------STEP 4\n"; + +foreach ($iterator as $item) { + $iterator->valid(); + echo $item->format('Y-m-d') . "\n"; +} +?> +--EXPECT-- +2022-01-01 +2022-01-02 +2022-01-03 +---------STEP 2 +2022-01-01 +2022-01-02 +2022-01-03 +---------STEP 3 +2022-01-02 +2022-01-03 +---------STEP 4 +2022-01-02 +2022-01-03