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; } }