public function parse(DateTimeParseContext $context, $text, $position)
 {
     // cache context before changed by decorated parser
     $strict = $context->isStrict();
     // parse
     if ($position > strlen($text) || $position < 0) {
         throw new \OutOfRangeException();
     }
     if ($position === strlen($text)) {
         return ~$position;
         // no more characters in the string
     }
     $endPos = $position + $this->padWidth;
     if ($endPos > strlen($text)) {
         if ($strict) {
             return ~$position;
             // not enough characters in the string to meet the parse width
         }
         $endPos = strlen($text);
     }
     $pos = $position;
     while ($pos < $endPos && $context->charEquals($text[$pos], $this->padChar)) {
         $pos++;
     }
     $text = substr($text, 0, $endPos);
     $resultPos = $this->printerParser->parse($context, $text, $pos);
     if ($resultPos !== $endPos && $strict) {
         return ~($position + $pos);
         // parse of decorated field didn't parse to the end
     }
     return $resultPos;
 }
 /**
  * Parse an offset following a prefix and set the ZoneId if it is valid.
  * To matching the parsing of ZoneId.of the values are not normalized
  * to ZoneOffsets.
  *
  * @param DateTimeParseContext $context the parse context
  * @param string $text the input text
  * @param int $prefixPos start of the prefix
  * @param int $position start of text after the prefix
  * @param OffsetIdPrinterParser $parser parser for the value after the prefix
  * @return int the position after the parse
  */
 private function parseOffsetBased(DateTimeParseContext $context, $text, $prefixPos, $position, OffsetIdPrinterParser $parser)
 {
     $prefix = strtoupper(substr($text, $prefixPos, $position - $prefixPos));
     if ($position >= strlen($text)) {
         $context->setParsedZone(ZoneId::of($prefix));
         return $position;
     }
     // '0' or 'Z' after prefix is not part of a valid ZoneId; use bare prefix
     if ($text[$position] === '0' || $context->charEquals($text[$position], 'Z')) {
         $context->setParsedZone(ZoneId::of($prefix));
         return $position;
     }
     $newContext = $context->copy();
     $endPos = $parser->parse($newContext, $text, $position);
     try {
         if ($endPos < 0) {
             if ($parser == OffsetIdPrinterParser::INSTANCE_ID_Z()) {
                 return ~$prefixPos;
             }
             $context->setParsedZone(ZoneId::of($prefix));
             return $position;
         }
         $offset = $newContext->getParsed(ChronoField::OFFSET_SECONDS());
         $zoneOffset = ZoneOffset::ofTotalSeconds($offset);
         $context->setParsedZone(ZoneId::ofOffset($prefix, $zoneOffset));
         return $endPos;
     } catch (DateTimeException $dte) {
         return ~$prefixPos;
     }
 }