original_string: protected function getRunDate($currentTime = null, $nth = 0, $invert = false, $allowCurrentDate = false)
      {
          if ($currentTime instanceof DateTime) {
              $currentDate = clone $currentTime;
          } elseif ($currentTime instanceof DateTimeImmutable) {
              $currentDate = DateTime::createFromFormat('U', $currentTime->format('U'));
              $currentDate->setTimezone($currentTime->getTimezone());
          } else {
              $currentDate = new DateTime($currentTime ?: 'now');
              $currentDate->setTimezone(new DateTimeZone(date_default_timezone_get()));
          }
  
          $currentDate->setTime($currentDate->format('H'), $currentDate->format('i'), 0);
          $nextRun = clone $currentDate;
          $nth = (int) $nth;
  
          // We don't have to satisfy * or null fields
          $parts = array();
          $fields = array();
          foreach (self::$order as $position) {
              $part = $this->getExpression($position);
              if (null === $part || '*' === $part) {
                  continue;
              }
              $parts[$position] = $part;
              $fields[$position] = $this->fieldFactory->getField($position);
          }
  
          // Set a hard limit to bail on an impossible date
          for ($i = 0; $i < $this->maxIterationCount; $i++) {
  
              foreach ($parts as $position => $part) {
                  $satisfied = false;
                  // Get the field object used to validate this part
                  $field = $fields[$position];
                  // Check if this is singular or a list
                  if (strpos($part, ',') === false) {
                      $satisfied = $field->isSatisfiedBy($nextRun, $part);
                  } else {
                      foreach (array_map('trim', explode(',', $part)) as $listPart) {
                          if ($field->isSatisfiedBy($nextRun, $listPart)) {
                              $satisfied = true;
                              break;
                          }
                      }
                  }
  
                  // If the field is not satisfied, then start over
                  if (!$satisfied) {
                      $field->increment($nextRun, $invert, $part);
                      continue 2;
                  }
              }
  
              // Skip this match if needed
              if ((!$allowCurrentDate && $nextRun == $currentDate) || --$nth > -1) {
                  $this->fieldFactory->getField(0)->increment($nextRun, $invert, isset($parts[0]) ? $parts[0] : null);
                  continue;
              }
  
              return $nextRun;
          }
  
          // @codeCoverageIgnoreStart
          throw new RuntimeException('Impossible CRON expression');
          // @codeCoverageIgnoreEnd
      }
code: protected function getRunDate($currentTime = null, $nth = 0, $invert = false, $allowCurrentDate = false)
      {
          if ($currentTime instanceof DateTime) {
              $currentDate = clone $currentTime;
          } elseif ($currentTime instanceof DateTimeImmutable) {
              $currentDate = DateTime::createFromFormat('U', $currentTime->format('U'));
              $currentDate->setTimezone($currentTime->getTimezone());
          } else {
              $currentDate = new DateTime($currentTime ?: 'now');
              $currentDate->setTimezone(new DateTimeZone(date_default_timezone_get()));
          }
  
          $currentDate->setTime($currentDate->format('H'), $currentDate->format('i'), 0);
          $nextRun = clone $currentDate;
          $nth = (int) $nth;
  
          // We don't have to satisfy * or null fields
          $parts = array();
          $fields = array();
          foreach (self::$order as $position) {
              $part = $this->getExpression($position);
              if (null === $part || '*' === $part) {
                  continue;
              }
              $parts[$position] = $part;
              $fields[$position] = $this->fieldFactory->getField($position);
          }
  
          // Set a hard limit to bail on an impossible date
          for ($i = 0; $i < $this->maxIterationCount; $i++) {
  
              foreach ($parts as $position => $part) {
                  $satisfied = false;
                  // Get the field object used to validate this part
                  $field = $fields[$position];
                  // Check if this is singular or a list
                  if (strpos($part, ',') === false) {
                      $satisfied = $field->isSatisfiedBy($nextRun, $part);
                  } else {
                      foreach (array_map('trim', explode(',', $part)) as $listPart) {
                          if ($field->isSatisfiedBy($nextRun, $listPart)) {
                              $satisfied = true;
                              break;
                          }
                      }
                  }
  
                  // If the field is not satisfied, then start over
                  if (!$satisfied) {
                      $field->increment($nextRun, $invert, $part);
                      continue 2;
                  }
              }
  
              // Skip this match if needed
              if ((!$allowCurrentDate && $nextRun == $currentDate) || --$nth > -1) {
                  $this->fieldFactory->getField(0)->increment($nextRun, $invert, isset($parts[0]) ? $parts[0] : null);
                  continue;
              }
  
              return $nextRun;
          }
  
          // @codeCoverageIgnoreStart
          throw new RuntimeException('Impossible CRON expression');
          // @codeCoverageIgnoreEnd
      }
code_tokens: protected function getRunDate ( $ currentTime = null , $ nth = 0 , $ invert = false , $ allowCurrentDate = false ) { if ( $ currentTime instanceof DateTime ) { $ currentDate = clone $ currentTime ; } elseif ( $ currentTime instanceof DateTimeImmutable ) { $ currentDate = DateTime :: createFromFormat ( 'U' , $ currentTime -> format ( 'U' ) ) ; $ currentDate -> setTimezone ( $ currentTime -> getTimezone ( ) ) ; } else { $ currentDate = new DateTime ( $ currentTime ? : 'now' ) ; $ currentDate -> setTimezone ( new DateTimeZone ( date_default_timezone_get ( ) ) ) ; } $ currentDate -> setTime ( $ currentDate -> format ( 'H' ) , $ currentDate -> format ( 'i' ) , 0 ) ; $ nextRun = clone $ currentDate ; $ nth = ( int ) $ nth ; // We don't have to satisfy * or null fields $ parts = array ( ) ; $ fields = array ( ) ; foreach ( self :: $ order as $ position ) { $ part = $ this -> getExpression ( $ position ) ; if ( null === $ part || '*' === $ part ) { continue ; } $ parts [ $ position ] = $ part ; $ fields [ $ position ] = $ this -> fieldFactory -> getField ( $ position ) ; } // Set a hard limit to bail on an impossible date for ( $ i = 0 ; $ i < $ this -> maxIterationCount ; $ i ++ ) { foreach ( $ parts as $ position => $ part ) { $ satisfied = false ; // Get the field object used to validate this part $ field = $ fields [ $ position ] ; // Check if this is singular or a list if ( strpos ( $ part , ',' ) === false ) { $ satisfied = $ field -> isSatisfiedBy ( $ nextRun , $ part ) ; } else { foreach ( array_map ( 'trim' , explode ( ',' , $ part ) ) as $ listPart ) { if ( $ field -> isSatisfiedBy ( $ nextRun , $ listPart ) ) { $ satisfied = true ; break ; } } } // If the field is not satisfied, then start over if ( ! $ satisfied ) { $ field -> increment ( $ nextRun , $ invert , $ part ) ; continue 2 ; } } // Skip this match if needed if ( ( ! $ allowCurrentDate && $ nextRun == $ currentDate ) || -- $ nth > - 1 ) { $ this -> fieldFactory -> getField ( 0 ) -> increment ( $ nextRun , $ invert , isset ( $ parts [ 0 ] ) ? $ parts [ 0 ] : null ) ; continue ; } return $ nextRun ; } // @codeCoverageIgnoreStart throw new RuntimeException ( 'Impossible CRON expression' ) ; // @codeCoverageIgnoreEnd }
docstring: Get the next or previous run date of the expression relative to a date
  
  @param string|\DateTime $currentTime      Relative calculation date
  @param int              $nth              Number of matches to skip before returning
  @param bool             $invert           Set to TRUE to go backwards in time
  @param bool             $allowCurrentDate Set to TRUE to return the
  current date if it matches the cron expression
  
  @return \DateTime
  @throws \RuntimeException on too many iterations
docstring_tokens: Get the next or previous run date of the expression relative to a date