/** * This implementation looks for the longest matching string. * For example, parsing Etc/GMT-2 will return Etc/GMC-2 rather than just * Etc/GMC although both are valid. */ public function parse(DateTimeParseContext $context, $text, $position) { $length = strlen($text); if ($position > $length) { throw new \OutOfRangeException(); } if ($position === $length) { return ~$position; } // handle fixed time-zone IDs $nextChar = $text[$position]; if ($nextChar === '+' || $nextChar === '-') { return $this->parseOffsetBased($context, $text, $position, $position, OffsetIdPrinterParser::INSTANCE_ID_Z()); } else { if ($length >= $position + 2) { $nextNextChar = $text[$position + 1]; if ($context->charEquals($nextChar, 'U') && $context->charEquals($nextNextChar, 'T')) { if ($length >= $position + 3 && $context->charEquals($text[$position + 2], 'C')) { return $this->parseOffsetBased($context, $text, $position, $position + 3, OffsetIdPrinterParser::INSTANCE_ID_ZERO()); } return $this->parseOffsetBased($context, $text, $position, $position + 2, OffsetIdPrinterParser::INSTANCE_ID_ZERO()); } else { if ($context->charEquals($nextChar, 'G') && $length >= $position + 3 && $context->charEquals($nextNextChar, 'M') && $context->charEquals($text[$position + 2], 'T')) { return $this->parseOffsetBased($context, $text, $position, $position + 3, OffsetIdPrinterParser::INSTANCE_ID_ZERO()); } } } } // parse $ppos = new ParsePosition($position); $parsedZoneId = $this->match($text, $ppos, $context->isCaseSensitive()); /* $tree = $this->getTree($context); $parsedZoneId = $tree->match($text, $ppos); */ if ($parsedZoneId === null) { if ($context->charEquals($nextChar, 'Z')) { $context->setParsedZone(ZoneOffset::UTC()); return $position + 1; } return ~$position; } $context->setParsedZone(ZoneId::of($parsedZoneId)); return $ppos->getIndex(); }