src/php/Arbit/Periodic/CronjobIterator.php
protected function getNextFutureTimestamp()
    {
        /*
        * To save time in pregeneration we use the array traversal functions
        * here to create iteratively accessed foreach loops on monthAndDays,
        * hours and minutes
        */

        // These values are only used if we are inside the current year
        // Because they will not change significantly during the loop we are
        // just generating them once.
        if ( $this->yearOffset === 0 )
        {
            $currentHour   = (int)date( 'H', $this->getCurrentTime() );
            $currentMinute = (int)date( 'i', $this->getCurrentTime() );
            $currentDay    = (int)date( 'd', $this->getCurrentTime() );
            $currentMonth  = (int)date( 'm', $this->getCurrentTime() );
        }

        do
        {
            // Initialize all timetable values with their current value
            $minute      = current( $this->minutes );
            $hour        = current( $this->hours );
            $monthAndDay = current( $this->monthAndDays );

            // Advance one step
            $minute = next( $this->minutes );
            if ( $minute === false )
            {
                // We reached the end of the minutes array. Therefore we need
                // to advance hours and reset minutes
                $minute = reset( $this->minutes );
                $hour = next( $this->hours );
                if ( $hour === false )
                {
                    // We reached the end of the hours array. Therefore we need
                    // to advance monthAndDays and reset hours
                    $hour = reset( $this->hours );
                    $monthAndDay = next( $this->monthAndDays );
                    if( $monthAndDay === false )
                    {
                        // We reached the end of monthAndDays. Therefore we
                        // need to generate new tables for the next year.
                        $this->generateTimetable( $this->yearOffset + 1 );

                        // Use the first entry of every timetable array
                        $minute      = reset( $this->minutes );
                        $hour        = reset( $this->hours );
                        $monthAndDay = reset( $this->monthAndDays );
                    }
                }
            }

            /*
             * We could use strtotime and just check against the timestamp here.
             * Unfortunately this would be slower by factor 3. Therefore this
             * manual checking routine is used
             */
            // Only the current year is of interest everything else is in the
            // future anyway.
            if ( $this->yearOffset === 0 )
            {
                if ( ( $month = (int)substr( $monthAndDay, 0, 2 ) ) === $currentMonth )
                {
                    if ( ( $day = (int)substr( $monthAndDay, 3, 2 ) ) < $currentDay )
                    {
                        continue;
                    }
                    if ( $day === $currentDay )
                    {
                        if ( $hour < $currentHour )
                        {
                            continue;
                        }
                        if ( $hour === $currentHour )
                        {
                            if ( $minute < $currentMinute )
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            $nextElement = strtotime(
                sprintf(
                    '%d-%s %02d:%02d:00',
                    $this->year + $this->yearOffset, $monthAndDay, $hour, $minute
                )
            );

            // The next element has been found, therefore the loop can be
            // broken
            break;

        } while( true );

        return $nextElement;
    }
protected function getNextFutureTimestamp()
    {
        /*
        * To save time in pregeneration we use the array traversal functions
        * here to create iteratively accessed foreach loops on monthAndDays,
        * hours and minutes
        */

        // These values are only used if we are inside the current year
        // Because they will not change significantly during the loop we are
        // just generating them once.
        if ( $this->yearOffset === 0 )
        {
            $currentHour   = (int)date( 'H', $this->getCurrentTime() );
            $currentMinute = (int)date( 'i', $this->getCurrentTime() );
            $currentDay    = (int)date( 'd', $this->getCurrentTime() );
            $currentMonth  = (int)date( 'm', $this->getCurrentTime() );
        }

        do
        {
            // Initialize all timetable values with their current value
            $minute      = current( $this->minutes );
            $hour        = current( $this->hours );
            $monthAndDay = current( $this->monthAndDays );

            // Advance one step
            $minute = next( $this->minutes );
            if ( $minute === false )
            {
                // We reached the end of the minutes array. Therefore we need
                // to advance hours and reset minutes
                $minute = reset( $this->minutes );
                $hour = next( $this->hours );
                if ( $hour === false )
                {
                    // We reached the end of the hours array. Therefore we need
                    // to advance monthAndDays and reset hours
                    $hour = reset( $this->hours );
                    $monthAndDay = next( $this->monthAndDays );
                    if( $monthAndDay === false )
                    {
                        // We reached the end of monthAndDays. Therefore we
                        // need to generate new tables for the next year.
                        $this->generateTimetable( $this->yearOffset + 1 );

                        // Use the first entry of every timetable array
                        $minute      = reset( $this->minutes );
                        $hour        = reset( $this->hours );
                        $monthAndDay = reset( $this->monthAndDays );
                    }
                }
            }

            /*
             * We could use strtotime and just check against the timestamp here.
             * Unfortunately this would be slower by factor 3. Therefore this
             * manual checking routine is used
             */
            // Only the current year is of interest everything else is in the
            // future anyway.
            if ( $this->yearOffset === 0 )
            {
                if ( ( $month = (int)substr( $monthAndDay, 0, 2 ) ) === $currentMonth )
                {
                    if ( ( $day = (int)substr( $monthAndDay, 3, 2 ) ) < $currentDay )
                    {
                        continue;
                    }
                    if ( $day === $currentDay )
                    {
                        if ( $hour < $currentHour )
                        {
                            continue;
                        }
                        if ( $hour === $currentHour )
                        {
                            if ( $minute < $currentMinute )
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            $nextElement = strtotime(
                sprintf(
                    '%d-%s %02d:%02d:00',
                    $this->year + $this->yearOffset, $monthAndDay, $hour, $minute
                )
            );

            // The next element has been found, therefore the loop can be
            // broken
            break;

        } while( true );

        return $nextElement;
    }
Return the next timestamp which lies in the future. This function
handles the regeneration of the timetable information on year boundaries
correctly.

@return int Timestamp of the next future event