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, $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)
 {
     $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);
 }
 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);
 }
 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;
 }