private ZonedDateTime nextClosestMatch(final ZonedDateTime date) throws NoSuchValueException {
        ExecutionTimeResult result = new ExecutionTimeResult(date, false);
        for (int i = 0; i < MAX_ITERATIONS; i++) {
            result = potentialNextClosestMatch(result.getTime());
            if (result.isMatch()) {
                return result.getTime();
            }
            if (result.getTime().getYear() - date.getYear() > 100) {
                throw new NoSuchValueException();
            }
        }

        throw new NoSuchValueException();
    }
private ZonedDateTime nextClosestMatch ( final ZonedDateTime date ) throws NoSuchValueException { ExecutionTimeResult result = new ExecutionTimeResult ( date , false ) ; for ( int i = 0 ; i < MAX_ITERATIONS ; i ++ ) { result = potentialNextClosestMatch ( result . getTime ( ) ) ; if ( result . isMatch ( ) ) { return result . getTime ( ) ; } if ( result . getTime ( ) . getYear ( ) - date . getYear ( ) > 100 ) { throw new NoSuchValueException ( ) ; } } throw new NoSuchValueException ( ) ; }
If date is not match, will return next closest match.
If date is match, will return this date.

@param date - reference ZonedDateTime instance - never null;
@return ZonedDateTime instance, never null. Value obeys logic specified above.
@throws NoSuchValueException if there is no potential next year