public function parse(DateTimeParseContext $context, $text, $position) { if ($context->getParsed($this->field) === null) { $context->setParsedField($this->field, $this->value, $position, $position); } return $position; }
public function parse(DateTimeParseContext $context, $text, $position) { // simple looping parser to find the chronology if ($position < 0 || $position > strlen($text)) { throw new IndexOutOfBoundsException(); } $chronos = AbstractChronology::getAvailableChronologies(); $bestMatch = null; $matchLen = -1; foreach ($chronos as $chrono) { if ($this->textStyle === null) { $name = $chrono->getId(); } else { $name = $this->getChronologyName($chrono, $context->getLocale()); } $nameLen = strlen($name); if ($nameLen > $matchLen && $context->subSequenceEquals($text, $position, $name, 0, $nameLen)) { $bestMatch = $chrono; $matchLen = $nameLen; } } if ($bestMatch === null) { return ~$position; } $context->setParsed($bestMatch); return $position + $matchLen; }
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; }
public function parse(DateTimeParseContext $context, $text, $position) { if ($this->optional) { $context->startOptional(); $pos = $position; foreach ($this->printerParsers as $pp) { $pos = $pp->parse($context, $text, $pos); if ($pos < 0) { $context->endOptional(false); return $position; // return original position } } $context->endOptional(true); return $pos; } else { foreach ($this->printerParsers as $pp) { $position = $pp->parse($context, $text, $position); if ($position < 0) { break; } } return $position; } }
public function parse(DateTimeParseContext $context, $text, $position) { $length = strlen($text); if ($position > $length || $position < 0) { throw new \OutOfRangeException(); } if ($context->subSequenceEquals($text, $position, $this->literal, 0, strlen($this->literal)) == false) { return ~$position; } return $position + strlen($this->literal); }
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 parse(DateTimeParseContext $context, $text, $position) { $length = strlen($text); if ($position === $length) { return ~$position; } if ($position < 0 || $position >= $length) { throw new \OutOfRangeException(); } $ch = $text[$position]; if ($ch !== $this->literal) { if ($context->isCaseSensitive() || strtoupper($ch) !== strtoupper($this->literal) && strtolower($ch) !== strtolower($this->literal)) { return ~$position; } } return $position + 1; }
public function parse(DateTimeParseContext $context, $text, $position) { // using ordinals to avoid javac synthetic inner class switch ($this->ordinal) { case 0: $context->setCaseSensitive(true); break; case 1: $context->setCaseSensitive(false); break; case 2: $context->setStrict(true); break; case 3: $context->setStrict(false); break; } return $position; }
public function parse(DateTimeParseContext $context, $text, $position) { $length = strlen($text); $noOffsetLen = strlen($this->noOffsetText); if ($noOffsetLen === 0) { if ($position === $length) { return $context->setParsedField(ChronoField::OFFSET_SECONDS(), 0, $position, $position); } } else { if ($position === $length) { return ~$position; } if ($context->subSequenceEquals($text, $position, $this->noOffsetText, 0, $noOffsetLen)) { return $context->setParsedField(ChronoField::OFFSET_SECONDS(), 0, $position, $position + $noOffsetLen); } } // parse normal plus/minus offset $sign = $text[$position]; // IOOBE if invalid position if ($sign === '+' || $sign === '-') { // starts $negative = $sign === '-' ? -1 : 1; $array = [0, 0, 0, 0]; $array[0] = $position + 1; if (($this->parseNumber($array, 1, $text, true) || $this->parseNumber($array, 2, $text, $this->type >= 3) || $this->parseNumber($array, 3, $text, false)) === false) { // success $offsetSecs = $negative * ($array[1] * 3600 + $array[2] * 60 + $array[3]); return $context->setParsedField(ChronoField::OFFSET_SECONDS(), $offsetSecs, $position, $array[0]); } } // handle special case of empty no offset text if ($noOffsetLen === 0) { return $context->setParsedField(ChronoField::OFFSET_SECONDS(), 0, $position, $position + $noOffsetLen); } return ~$position; }
public function parse(DateTimeParseContext $context, $text, $position) { $pos = $position; $end = $pos + strlen($text); $gmtText = "GMT"; // TODO: get localized version of 'GMT' if ($gmtText !== null) { if (!$context->subSequenceEquals($text, $pos, $gmtText, 0, strlen($gmtText))) { return ~$position; } $pos += strlen($gmtText); } // parse normal plus/minus offset if ($pos == $end) { return $context->setParsedField(ChronoField::OFFSET_SECONDS(), 0, $position, $pos); } $sign = $text[$pos]; // IOOBE if invalid position if ($sign == '+') { $negative = 1; } else { if ($sign == '-') { $negative = -1; } else { return $context->setParsedField(ChronoField::OFFSET_SECONDS(), 0, $position, $pos); } } $pos++; $m = 0; $s = 0; if ($this->style == TextStyle::FULL()) { $h1 = $this->getDigit($text, $pos++); $h2 = $this->getDigit($text, $pos++); if ($h1 < 0 || $h2 < 0 || $text[$pos++] !== ':') { return ~$position; } $h = $h1 * 10 + $h2; $m1 = $this->getDigit($text, $pos++); $m2 = $this->getDigit($text, $pos++); if ($m1 < 0 || $m2 < 0) { return ~$position; } $m = $m1 * 10 + $m2; if ($pos + 2 < $end && $text[$pos] === ':') { $s1 = $this->getDigit($text, $pos + 1); $s2 = $this->getDigit($text, $pos + 2); if ($s1 >= 0 && $s2 >= 0) { $s = $s1 * 10 + $s2; $pos += 3; } } } else { $h = $this->getDigit($text, $pos++); if ($h < 0) { return ~$position; } if ($pos < $end) { $h2 = $this->getDigit($text, $pos); if ($h2 >= 0) { $h = $h * 10 + $h2; $pos++; } if ($pos + 2 < $end && $text[$pos] === ':') { if ($pos + 2 < $end && $text[$pos] === ':') { $m1 = $this->getDigit($text, $pos + 1); $m2 = $this->getDigit($text, $pos + 2); if ($m1 >= 0 && $m2 >= 0) { $m = $m1 * 10 + $m2; $pos += 3; if ($pos + 2 < $end && $text[$pos] === ':') { $s1 = $this->getDigit($text, $pos + 1); $s2 = $this->getDigit($text, $pos + 2); if ($s1 >= 0 && $s2 >= 0) { $s = $s1 * 10 + $s2; $pos += 3; } } } } } } } $offsetSecs = $negative * ($h * 3600 + $m * 60 + $s); return $context->setParsedField(ChronoField::OFFSET_SECONDS(), $offsetSecs, $position, $pos); }
/** * Stores the value. * * @param DateTimeParseContext $context the context to store into, not null * @param int $value the value * @param int $errorPos the position of the field being parsed * @param int $successPos the position after the field being parsed * @return int the new position */ public function setValue(DateTimeParseContext $context, $value, $errorPos, $successPos) { return $context->setParsedField($this->field, $value, $errorPos, $successPos); }
public function parse(DateTimeParseContext $context, $text, $position) { $effectiveMin = $context->isStrict() ? $this->minWidth : 0; $effectiveMax = $context->isStrict() ? $this->maxWidth : 9; $length = strlen($text); if ($position === $length) { // valid if whole field is optional, invalid if minimum width return $effectiveMin > 0 ? ~$position : $position; } if ($this->decimalPoint) { if ($text[$position] != $context->getDecimalStyle()->getDecimalSeparator()) { // valid if whole field is optional, invalid if minimum width return $effectiveMin > 0 ? ~$position : $position; } $position++; } $minEndPos = $position + $effectiveMin; if ($minEndPos > $length) { return ~$position; // need at least min width digits } $maxEndPos = Math::min($position + $effectiveMax, $length); $total = 0; // can use int because we are only parsing up to 9 digits $pos = $position; while ($pos < $maxEndPos) { $ch = $text[$pos++]; $digit = $context->getDecimalStyle()->convertToDigit($ch); if ($digit < 0) { if ($pos < $minEndPos) { return ~$position; // need at least min width digits } $pos--; break; } $total = $total * 10 + $digit; } $div = 1 . str_repeat('0', 9 - ($pos - $position)); $fraction = gmp_mul($total, $div); $value = $this->convertFromFraction($fraction); return $context->setParsedField($this->field, $value, $position, $pos); }
/** * 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; } }
/** * For a ReducedPrinterParser, fixed width is false if the mode is strict, * otherwise it is set as for NumberPrinterParser. * @param DateTimeParseContext $context the context * @return bool if the field is fixed width * @see DateTimeFormatterBuilder#appendValueReduced(java.time.temporal.TemporalField, int, int, int) */ public function isFixedWidth(DateTimeParseContext $context) { if ($context->isStrict() == false) { return false; } return parent::isFixedWidth($context); }
public function parse(DateTimeParseContext $context, $text, $position) { $chrono = $context->getEffectiveChronology(); return $this->formatter($context->getLocale(), $chrono)->toPrinterParser(false)->parse($context, $text, $position); }
public function parse(DateTimeParseContext $context, $text, $position) { // TODO cache formatter // new context to avoid overwriting fields like year/month/day $minDigits = $this->fractionalDigits < 0 ? 0 : $this->fractionalDigits; $maxDigits = $this->fractionalDigits < 0 ? 9 : $this->fractionalDigits; $parser = (new DateTimeFormatterBuilder())->append(DateTimeFormatter::ISO_LOCAL_DATE())->appendLiteral('T')->appendValue2(ChronoField::HOUR_OF_DAY(), 2)->appendLiteral(':')->appendValue2(ChronoField::MINUTE_OF_HOUR(), 2)->appendLiteral(':')->appendValue2(ChronoField::SECOND_OF_MINUTE(), 2)->appendFraction(ChronoField::NANO_OF_SECOND(), $minDigits, $maxDigits, true)->appendLiteral('Z')->toFormatter()->toPrinterParser(false); $newContext = $context->copy(); $pos = $parser->parse($newContext, $text, $position); if ($pos < 0) { return $pos; } // parser restricts most fields to 2 digits, so definitely int // correctly parsed nano is also guaranteed to be valid $yearParsed = $newContext->getParsed(ChronoField::YEAR()); $month = $newContext->getParsed(ChronoField::MONTH_OF_YEAR()); $day = $newContext->getParsed(ChronoField::DAY_OF_MONTH()); $hour = $newContext->getParsed(ChronoField::HOUR_OF_DAY()); $min = $newContext->getParsed(ChronoField::MINUTE_OF_HOUR()); $secVal = $newContext->getParsed(ChronoField::SECOND_OF_MINUTE()); $nanoVal = $newContext->getParsed(ChronoField::NANO_OF_SECOND()); $sec = $secVal !== null ? $secVal : 0; $nano = $nanoVal !== null ? $nanoVal : 0; $days = 0; if ($hour === 24 && $min === 0 && $sec === 0 && $nano === 0) { $hour = 0; $days = 1; } else { if ($hour === 23 && $min === 59 && $sec === 60) { $context->setParsedLeapSecond(); $sec = 59; } } $year = $yearParsed % 10000; try { $ldt = LocalDateTime::of($year, $month, $day, $hour, $min, $sec, 0)->plusDays($days); $instantSecs = $ldt->toEpochSecond(ZoneOffset::UTC()); $instantSecs += Math::multiplyExact(Math::div($yearParsed, 10000), self::SECONDS_PER_10000_YEARS); } catch (RuntimeException $ex) { // TODO What do we actually catch here and why return ~$position; } $successPos = $pos; $successPos = $context->setParsedField(ChronoField::INSTANT_SECONDS(), $instantSecs, $position, $successPos); return $context->setParsedField(ChronoField::NANO_OF_SECOND(), $nano, $position, $successPos); }