public function setValue(DateTimeParseContext $context, $value, $errorPos, $successPos) { $baseValue = $this->baseValue; if ($this->baseDate !== null) { $chrono = $context->getEffectiveChronology(); $baseValue = $chrono->dateFrom($this->baseDate)->get($this->field); // In case the Chronology is changed later, add a callback when/if it changes $initialValue = $value; $context->addChronoChangedListener(function ($_) use($context, $initialValue, $errorPos, $successPos) { /* Repeat the set of the field using the current Chronology * The success/error position is ignored because the value is * intentionally being overwritten. */ $this->setValue($context, $initialValue, $errorPos, $successPos); }); } $parseLen = $successPos - $errorPos; if ($parseLen == $this->minWidth && $value >= 0) { $range = self::$EXCEED_POINTS[$this->minWidth]; $lastPart = $baseValue % $range; $basePart = $baseValue - $lastPart; if ($baseValue > 0) { $value = $basePart + $value; } else { $value = $basePart - $value; } if ($value < $baseValue) { $value += $range; } } return $context->setParsedField($this->field, $value, $errorPos, $successPos); }