public function __toString() { $sb = "Localized("; if ($this->chr === 'Y') { if ($this->count == 1) { $sb .= "WeekBasedYear"; } else { if ($this->count == 2) { $sb .= "ReducedValue(WeekBasedYear,2,2,2000-01-01)"; } else { $sb .= "WeekBasedYear," . $this->count . "," . 19 . "," . ($this->count < 4 ? SignStyle::NORMAL() : SignStyle::EXCEEDS_PAD()); } } } else { switch ($this->chr) { case 'c': case 'e': $sb .= "DayOfWeek"; break; case 'w': $sb .= "WeekOfWeekBasedYear"; break; case 'W': $sb .= "WeekOfMonth"; break; default: break; } $sb .= ","; $sb .= $this->count; } $sb .= ")"; return $sb; }
public function parse(DateTimeParseContext $context, $text, $position) { $length = strlen($text); if ($position === $length) { return ~$position; } if ($position < 0 || $position >= $length) { throw new \OutOfRangeException(); } $sign = $text[$position]; $negative = false; $positive = false; if ($sign === $context->getDecimalStyle()->getPositiveSign()) { if ($this->signStyle->parse(true, $context->isStrict(), $this->minWidth === $this->maxWidth) === false) { return ~$position; } $positive = true; $position++; } else { if ($sign === $context->getDecimalStyle()->getNegativeSign()) { if ($this->signStyle->parse(false, $context->isStrict(), $this->minWidth === $this->maxWidth) === false) { return ~$position; } $negative = true; $position++; } else { if ($this->signStyle == SignStyle::ALWAYS() && $context->isStrict()) { return ~$position; } } } $effMinWidth = $context->isStrict() || $this->isFixedWidth($context) ? $this->minWidth : 1; $minEndPos = $position + $effMinWidth; if ($minEndPos > $length) { return ~$position; } $effMaxWidth = ($context->isStrict() || $this->isFixedWidth($context) ? $this->maxWidth : 9) + Math::max($this->subsequentWidth, 0); $total = 0; $totalBig = null; $pos = $position; for ($pass = 0; $pass < 2; $pass++) { $maxEndPos = Math::min($pos + $effMaxWidth, $length); while ($pos < $maxEndPos) { $ch = $text[$pos++]; $digit = $context->getDecimalStyle()->convertToDigit($ch); if ($digit < 0) { $pos--; if ($pos < $minEndPos) { return ~$position; // need at least min width digits } break; } if ($pos - $position > 18) { if ($totalBig === null) { $totalBig = \gmp_init($total); } $totalBig = \gmp_add(\gmp_mul($totalBig, "10"), \gmp_init($digit)); } else { $total = $total * 10 + $digit; } } if ($this->subsequentWidth > 0 && $pass === 0) { // re-parse now we know the correct width $parseLen = $pos - $position; $effMaxWidth = Math::max($effMinWidth, $parseLen - $this->subsequentWidth); $pos = $position; $total = 0; $totalBig = null; } else { break; } } if ($negative) { if ($totalBig !== null) { if (\gmp_cmp($totalBig, "0") === 0 && $context->isStrict()) { return ~($position - 1); // minus zero not allowed } $totalBig = \gmp_neg($totalBig); } else { if ($total === 0 && $context->isStrict()) { return ~($position - 1); // minus zero not allowed } $total = -$total; } } else { if ($this->signStyle == SignStyle::EXCEEDS_PAD() && $context->isStrict()) { $parseLen = $pos - $position; if ($positive) { if ($parseLen <= $this->minWidth) { return ~($position - 1); // '+' only parsed if minWidth exceeded } } else { if ($parseLen > $this->minWidth) { return ~$position; // '+' must be parsed if minWidth exceeded } } } } if ($totalBig !== null) { if (gmp_cmp($totalBig, "-9223372036854775808") < 0 || gmp_cmp($totalBig, "9223372036854775807") > 0) { // overflow, parse 1 less digit $totalBig = gmp_div($totalBig, "10"); $pos--; } return $this->setValue($context, gmp_intval($totalBig), $position, $pos); } return $this->setValue($context, $total, $position, $pos); }
/** * @dataProvider provider_pad */ public function test_pad_EXCEEDS_PAD($minPad, $maxPad, $value, $result) { try { $this->getFormatterWidth(ChronoField::DAY_OF_MONTH(), $minPad, $maxPad, SignStyle::EXCEEDS_PAD())->formatTo(new MockFieldValue(ChronoField::DAY_OF_MONTH(), $value), $buf); if ($result == null) { $this->fail("Expected exception"); return; // unreachable } if (strlen($result) > $minPad || $value < 0) { $result = $value < 0 ? "-" . $result : "+" . $result; } $this->assertEquals($buf, $result); } catch (DateTimeException $ex) { if ($result !== null) { throw $ex; } $this->assertEquals(strpos($ex->getMessage(), ChronoField::DAY_OF_MONTH()->__toString()) !== false, true); } }
private static function PARSER() { if (self::$PARSER === null) { self::$PARSER = (new DateTimeFormatterBuilder())->appendValue3(ChronoField::YEAR(), 4, 10, SignStyle::EXCEEDS_PAD())->toFormatter(); } return self::$PARSER; }
public function data_signStyle() { return [[LocalDate::of(0, 10, 2), SignStyle::ALWAYS(), null, "+00"], [LocalDate::of(2001, 10, 2), SignStyle::ALWAYS(), null, "+2001"], [LocalDate::of(-2001, 10, 2), SignStyle::ALWAYS(), null, "-2001"], [LocalDate::of(2001, 10, 2), SignStyle::NORMAL(), null, "2001"], [LocalDate::of(-2001, 10, 2), SignStyle::NORMAL(), null, "-2001"], [LocalDate::of(2001, 10, 2), SignStyle::NEVER(), null, "2001"], [LocalDate::of(-2001, 10, 2), SignStyle::NEVER(), null, "2001"], [LocalDate::of(2001, 10, 2), SignStyle::NOT_NEGATIVE(), null, "2001"], [LocalDate::of(-2001, 10, 2), SignStyle::NOT_NEGATIVE(), DateTimeException::class, ""], [LocalDate::of(0, 10, 2), SignStyle::EXCEEDS_PAD(), null, "00"], [LocalDate::of(1, 10, 2), SignStyle::EXCEEDS_PAD(), null, "01"], [LocalDate::of(-1, 10, 2), SignStyle::EXCEEDS_PAD(), null, "-01"], [LocalDate::of(20001, 10, 2), SignStyle::ALWAYS(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::NORMAL(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::NEVER(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::EXCEEDS_PAD(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::NOT_NEGATIVE(), DateTimeException::class, ""]]; }
public static function ISO_WEEK_DATE() { return self::$ISO_WEEK_DATE = (new DateTimeFormatterBuilder())->parseCaseInsensitive()->appendValue3(IsoFields::WEEK_BASED_YEAR(), 4, 10, SignStyle::EXCEEDS_PAD())->appendLiteral2("-W")->appendValue2(IsoFields::WEEK_OF_WEEK_BASED_YEAR(), 2)->appendLiteral('-')->appendValue2(ChronoField::DAY_OF_WEEK(), 1)->optionalStart()->appendOffsetId()->toFormatter3(ResolverStyle::STRICT(), IsoChronology::INSTANCE()); }
public static function init() { self::$PARSER = (new DateTimeFormatterBuilder())->appendValue3(ChronoField::YEAR(), 4, 10, SignStyle::EXCEEDS_PAD())->appendLiteral('-')->appendValue2(ChronoField::MONTH_OF_YEAR(), 2)->toFormatter(); }
public function provider_parseDigitsLenient() { return [["5", 1, 2, SignStyle::NEVER(), 1, 5], ["5", 2, 2, SignStyle::NEVER(), 1, 5], ["54", 1, 3, SignStyle::NEVER(), 2, 54], ["54", 2, 3, SignStyle::NEVER(), 2, 54], ["54", 3, 3, SignStyle::NEVER(), 2, 54], ["543", 1, 3, SignStyle::NEVER(), 3, 543], ["543", 2, 3, SignStyle::NEVER(), 3, 543], ["543", 3, 3, SignStyle::NEVER(), 3, 543], ["5432", 1, 3, SignStyle::NEVER(), 4, 5432], ["5432", 2, 3, SignStyle::NEVER(), 4, 5432], ["5432", 3, 3, SignStyle::NEVER(), 4, 5432], ["5AAA", 2, 3, SignStyle::NEVER(), 1, 5], ["5", 1, 2, SignStyle::NOT_NEGATIVE(), 1, 5], ["5", 2, 2, SignStyle::NOT_NEGATIVE(), 1, 5], ["54", 1, 3, SignStyle::NOT_NEGATIVE(), 2, 54], ["54", 2, 3, SignStyle::NOT_NEGATIVE(), 2, 54], ["54", 3, 3, SignStyle::NOT_NEGATIVE(), 2, 54], ["543", 1, 3, SignStyle::NOT_NEGATIVE(), 3, 543], ["543", 2, 3, SignStyle::NOT_NEGATIVE(), 3, 543], ["543", 3, 3, SignStyle::NOT_NEGATIVE(), 3, 543], ["5432", 1, 3, SignStyle::NOT_NEGATIVE(), 4, 5432], ["5432", 2, 3, SignStyle::NOT_NEGATIVE(), 4, 5432], ["5432", 3, 3, SignStyle::NOT_NEGATIVE(), 4, 5432], ["5AAA", 2, 3, SignStyle::NOT_NEGATIVE(), 1, 5], ["5", 1, 2, SignStyle::NORMAL(), 1, 5], ["5", 2, 2, SignStyle::NORMAL(), 1, 5], ["54", 1, 3, SignStyle::NORMAL(), 2, 54], ["54", 2, 3, SignStyle::NORMAL(), 2, 54], ["54", 3, 3, SignStyle::NORMAL(), 2, 54], ["543", 1, 3, SignStyle::NORMAL(), 3, 543], ["543", 2, 3, SignStyle::NORMAL(), 3, 543], ["543", 3, 3, SignStyle::NORMAL(), 3, 543], ["5432", 1, 3, SignStyle::NORMAL(), 4, 5432], ["5432", 2, 3, SignStyle::NORMAL(), 4, 5432], ["5432", 3, 3, SignStyle::NORMAL(), 4, 5432], ["5AAA", 2, 3, SignStyle::NORMAL(), 1, 5], ["5", 1, 2, SignStyle::ALWAYS(), 1, 5], ["5", 2, 2, SignStyle::ALWAYS(), 1, 5], ["54", 1, 3, SignStyle::ALWAYS(), 2, 54], ["54", 2, 3, SignStyle::ALWAYS(), 2, 54], ["54", 3, 3, SignStyle::ALWAYS(), 2, 54], ["543", 1, 3, SignStyle::ALWAYS(), 3, 543], ["543", 2, 3, SignStyle::ALWAYS(), 3, 543], ["543", 3, 3, SignStyle::ALWAYS(), 3, 543], ["5432", 1, 3, SignStyle::ALWAYS(), 4, 5432], ["5432", 2, 3, SignStyle::ALWAYS(), 4, 5432], ["5432", 3, 3, SignStyle::ALWAYS(), 4, 5432], ["5AAA", 2, 3, SignStyle::ALWAYS(), 1, 5], ["5", 1, 2, SignStyle::EXCEEDS_PAD(), 1, 5], ["5", 2, 2, SignStyle::EXCEEDS_PAD(), 1, 5], ["54", 1, 3, SignStyle::EXCEEDS_PAD(), 2, 54], ["54", 2, 3, SignStyle::EXCEEDS_PAD(), 2, 54], ["54", 3, 3, SignStyle::EXCEEDS_PAD(), 2, 54], ["543", 1, 3, SignStyle::EXCEEDS_PAD(), 3, 543], ["543", 2, 3, SignStyle::EXCEEDS_PAD(), 3, 543], ["543", 3, 3, SignStyle::EXCEEDS_PAD(), 3, 543], ["5432", 1, 3, SignStyle::EXCEEDS_PAD(), 4, 5432], ["5432", 2, 3, SignStyle::EXCEEDS_PAD(), 4, 5432], ["5432", 3, 3, SignStyle::EXCEEDS_PAD(), 4, 5432], ["5AAA", 2, 3, SignStyle::EXCEEDS_PAD(), 1, 5]]; }
public function test_appendValue_subsequent3_parse6() { $this->builder->appendValue3(CF::YEAR(), 4, 10, SignStyle::EXCEEDS_PAD())->appendValue2(CF::MONTH_OF_YEAR(), 2)->appendValue2(CF::DAY_OF_MONTH(), 2); $f = $this->builder->toFormatter(); $this->assertEquals($f->__toString(), "Value(Year,4,10,EXCEEDS_PAD)Value(MonthOfYear,2)Value(DayOfMonth,2)"); $parsed = $f->parseUnresolved("20090630", new ParsePosition(0)); $this->assertEquals($parsed->getLong(CF::YEAR()), 2009); $this->assertEquals($parsed->getLong(CF::MONTH_OF_YEAR()), 6); $this->assertEquals($parsed->getLong(CF::DAY_OF_MONTH()), 30); }
private function parseField($cur, $count, TemporalField $field) { $standalone = false; switch ($cur) { case 'u': case 'y': if ($count === 2) { $this->appendValueReduced2($field, 2, 2, ReducedPrinterParser::BASE_DATE()); } else { if ($count < 4) { $this->appendValue3($field, $count, 19, SignStyle::NORMAL()); } else { $this->appendValue3($field, $count, 19, SignStyle::EXCEEDS_PAD()); } } break; /** @noinspection PhpMissingBreakStatementInspection */ /** @noinspection PhpMissingBreakStatementInspection */ case 'c': if ($count === 2) { throw new IllegalArgumentException("Invalid pattern \"cc\""); } /*fallthrough*/ /*fallthrough*/ case 'L': /** @noinspection PhpMissingBreakStatementInspection */ /** @noinspection PhpMissingBreakStatementInspection */ case 'q': $standalone = true; /*fallthrough*/ /*fallthrough*/ case 'M': case 'Q': case 'E': case 'e': switch ($count) { case 1: case 2: if ($cur == 'c' || $cur == 'e') { $this->appendInternal(new WeekBasedFieldPrinterParser($cur, $count)); } else { if ($cur == 'E') { $this->appendText2($field, TextStyle::SHORT()); } else { if ($count === 1) { $this->appendValue($field); } else { $this->appendValue2($field, 2); } } } break; case 3: $this->appendText2($field, $standalone ? TextStyle::SHORT_STANDALONE() : TextStyle::SHORT()); break; case 4: $this->appendText2($field, $standalone ? TextStyle::FULL_STANDALONE() : TextStyle::FULL()); break; case 5: $this->appendText2($field, $standalone ? TextStyle::NARROW_STANDALONE() : TextStyle::NARROW()); break; default: throw new IllegalArgumentException("Too many pattern letters: " . $cur); } break; case 'a': if ($count === 1) { $this->appendText2($field, TextStyle::SHORT()); } else { throw new IllegalArgumentException("Too many pattern letters: " . $cur); } break; case 'G': switch ($count) { case 1: case 2: case 3: $this->appendText2($field, TextStyle::SHORT()); break; case 4: $this->appendText2($field, TextStyle::FULL()); break; case 5: $this->appendText2($field, TextStyle::NARROW()); break; default: throw new IllegalArgumentException("Too many pattern letters: " . $cur); } break; case 'S': $this->appendFraction(ChronoField::NANO_OF_SECOND(), $count, $count, false); break; case 'F': if ($count == 1) { $this->appendValue($field); } else { throw new IllegalArgumentException("Too many pattern letters: " . $cur); } break; case 'd': case 'h': case 'H': case 'k': case 'K': case 'm': case 's': if ($count === 1) { $this->appendValue($field); } else { if ($count === 2) { $this->appendValue2($field, $count); } else { throw new IllegalArgumentException("Too many pattern letters: " . $cur); } } break; case 'D': if ($count == 1) { $this->appendValue($field); } else { if ($count <= 3) { $this->appendValue2($field, $count); } else { throw new IllegalArgumentException("Too many pattern letters: " . $cur); } } break; default: if ($count == 1) { $this->appendValue($field); } else { $this->appendValue2($field, $count); } break; } }