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;
 }
示例#8
0
 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);
 }