public function parse(DateTimeParseContext $context, $parseText, $position)
 {
     $length = strlen($parseText);
     if ($position < 0 || $position > $length) {
         throw new \OutOfRangeException();
     }
     $style = $context->isStrict() ? $this->textStyle : null;
     $chrono = $context->getEffectiveChronology();
     $it = null;
     if ($chrono === null || $chrono == IsoChronology::INSTANCE()) {
         $it = $this->provider->getTextIterator($this->field, $style, $context->getLocale());
     } else {
         $it = $this->provider->getTextIterator2($chrono, $this->field, $style, $context->getLocale());
     }
     if ($it !== null) {
         foreach ($it as $key => $value) {
             // fix numeric indices
             $key = strval($key);
             if ($context->subSequenceEquals($key, 0, $parseText, $position, strlen($key))) {
                 return $context->setParsedField($this->field, $value, $position, $position + strlen($key));
             }
         }
         if ($context->isStrict()) {
             return ~$position;
         }
     }
     return $this->numberPrinterParser()->parse($context, $parseText, $position);
 }
 public function setValue(DateTimeParseContext $context, $value, $errorPos, $successPos)
 {
     $baseValue = $this->baseValue;
     if ($this->baseDate !== null) {
         $chrono = $context->getEffectiveChronology();
         $baseValue = $chrono->dateFrom($this->baseDate)->get($this->field);
         // In case the Chronology is changed later, add a callback when/if it changes
         $initialValue = $value;
         $context->addChronoChangedListener(function ($_) use($context, $initialValue, $errorPos, $successPos) {
             /* Repeat the set of the field using the current Chronology
              * The success/error position is ignored because the value is
              * intentionally being overwritten.
              */
             $this->setValue($context, $initialValue, $errorPos, $successPos);
         });
     }
     $parseLen = $successPos - $errorPos;
     if ($parseLen == $this->minWidth && $value >= 0) {
         $range = self::$EXCEED_POINTS[$this->minWidth];
         $lastPart = $baseValue % $range;
         $basePart = $baseValue - $lastPart;
         if ($baseValue > 0) {
             $value = $basePart + $value;
         } else {
             $value = $basePart - $value;
         }
         if ($value < $baseValue) {
             $value += $range;
         }
     }
     return $context->setParsedField($this->field, $value, $errorPos, $successPos);
 }
 public function parse(DateTimeParseContext $context, $text, $position)
 {
     $chrono = $context->getEffectiveChronology();
     return $this->formatter($context->getLocale(), $chrono)->toPrinterParser(false)->parse($context, $text, $position);
 }