public function resolve(FieldValues $fieldValues, TemporalAccessor $partialTemporal, ResolverStyle $resolverStyle) { $yearLong = $fieldValues->get(ChronoField::YEAR()); $qoyLong = $fieldValues->get(IsoFields::QUARTER_OF_YEAR()); if ($yearLong === null || $qoyLong === null) { return null; } $y = ChronoField::YEAR()->checkValidIntValue($yearLong); // always validate $doq = $fieldValues->get(IsoFields::DAY_OF_QUARTER()); IsoFields::ensureIso($partialTemporal); if ($resolverStyle == ResolverStyle::LENIENT()) { $date = LocalDate::of($y, 1, 1)->plusMonths(Math::multiplyExact(Math::subtractExact($qoyLong, 1), 3)); $doq = Math::subtractExact($doq, 1); } else { $qoy = IsoFields::QUARTER_OF_YEAR()->range()->checkValidIntValue($qoyLong, IsoFields::QUARTER_OF_YEAR()); // validated $date = LocalDate::of($y, ($qoy - 1) * 3 + 1, 1); if ($doq < 1 || $doq > 90) { if ($resolverStyle == ResolverStyle::STRICT()) { $this->rangeRefinedBy($date)->checkValidValue($doq, $this); // only allow exact range } else { // SMART $this->range()->checkValidValue($doq, $this); // allow 1-92 rolling into next quarter } } $doq--; } $fieldValues->remove($this); $fieldValues->remove(ChronoField::YEAR()); $fieldValues->remove(IsoFields::QUARTER_OF_YEAR()); return $date->plusDays($doq); }
public function resolve(FieldValues $fieldValues, TemporalAccessor $partialTemporal, ResolverStyle $resolverStyle) { $wbyLong = $fieldValues->get(IsoFields::WEEK_BASED_YEAR()); $dowLong = $fieldValues->get(ChronoField::DAY_OF_WEEK()); if ($wbyLong === null || $dowLong === null) { return null; } $wby = IsoFields::WEEK_BASED_YEAR()->range()->checkValidIntValue($wbyLong, IsoFields::WEEK_BASED_YEAR()); // always validate $wowby = $fieldValues->get(IsoFields::WEEK_OF_WEEK_BASED_YEAR()); IsoFields::ensureIso($partialTemporal); $date = LocalDate::of($wby, 1, 4); if ($resolverStyle == ResolverStyle::LENIENT()) { $dow = $dowLong; // unvalidated if ($dow > 7) { $date = $date->plusWeeks(Math::div($dow - 1, 7)); $dow = ($dow - 1) % 7 + 1; } else { if ($dow < 1) { $date = $date->plusWeeks(Math::div(Math::subtractExact($dow, 7), 7)); $dow = ($dow + 6) % 7 + 1; } } $date = $date->plusWeeks(Math::subtractExact($wowby, 1))->with(ChronoField::DAY_OF_WEEK(), $dow); } else { $dow = ChronoField::DAY_OF_WEEK()->checkValidIntValue($dowLong); // validated if ($wowby < 1 || $wowby > 52) { if ($resolverStyle == ResolverStyle::STRICT()) { IsoFields::getWeekRange($date)->checkValidValue($wowby, $this); // only allow exact range } else { // SMART $this->range()->checkValidValue($wowby, $this); // allow 1-53 rolling into next year } } $date = $date->plusWeeks($wowby - 1)->with(ChronoField::DAY_OF_WEEK(), $dow); } $fieldValues->remove($this); $fieldValues->remove(IsoFields::WEEK_BASED_YEAR()); $fieldValues->remove(ChronoField::DAY_OF_WEEK()); return $date; }
public function resolve(FieldValues $fieldValues, TemporalAccessor $partialTemporal, ResolverStyle $resolverStyle) { $value = $fieldValues->remove($this); $chrono = AbstractChronology::from($partialTemporal); if ($resolverStyle == ResolverStyle::LENIENT()) { return $chrono->dateEpochDay(Math::subtractExact($value, $this->offset)); } $this->range()->checkValidValue($value, $this); return $chrono->dateEpochDay($value - $this->offset); }
function resolveYMD(FieldValues $fieldValues, ResolverStyle $resolverStyle) { $y = CF::YEAR()->checkValidIntValue($fieldValues->remove(CF::YEAR())); if ($resolverStyle == ResolverStyle::LENIENT()) { $months = Math::subtractExact($fieldValues->remove(CF::MONTH_OF_YEAR()), 1); $days = Math::subtractExact($fieldValues->remove(CF::DAY_OF_MONTH()), 1); return LocalDate::of($y, 1, 1)->plusMonths($months)->plusDays($days); } $moy = CF::MONTH_OF_YEAR()->checkValidIntValue($fieldValues->remove(CF::MONTH_OF_YEAR())); $dom = CF::DAY_OF_MONTH()->checkValidIntValue($fieldValues->remove(CF::DAY_OF_MONTH())); if ($resolverStyle == ResolverStyle::SMART()) { // previous valid if ($moy == 4 || $moy == 6 || $moy == 9 || $moy == 11) { $dom = Math::min($dom, 30); } else { if ($moy == 2) { $dom = Math::min($dom, Month::FEBRUARY()->length(Year::isLeapYear($y))); } } } return LocalDate::of($y, $moy, $dom); }
/** * Adds a field-value pair to the map, checking for conflicts. * <p> * If the field is not already present, then the field-value pair is added to the map. * If the field is already present and it has the same value as that specified, no action occurs. * If the field is already present and it has a different value to that specified, then * an exception is thrown. * * @param FieldValues $fieldValues the map of fields to values, which can be updated, not null * @param ChronoField $field the field to add, not null * @param int $value the value to add, not null * @throws DateTimeException */ protected static function addFieldValue(FieldValues $fieldValues, ChronoField $field, $value) { $old = $fieldValues->put($field, $value); // check first for better error message if ($old !== null && $old !== $value) { throw new DateTimeException("Conflict found: " . $field . " " . $old . " differs from " . $field . " " . $value); } }
private function crossCheck1(TemporalAccessor $target) { foreach ($this->fieldValues as $field => $entry) { /** @var CF $field */ if ($target->isSupported($field)) { try { $val1 = $target->getLong($field); } catch (\RuntimeException $ex) { continue; } $val2 = $entry; if ($val1 !== $val2) { throw new DateTimeException("Conflict found: Field " . $field . " " . $val1 . " differs from " . $field . " " . $val2 . " derived from " . $target); } $this->fieldValues->remove($field); } } }
/** * @dataProvider data_resolve_ymaa */ public function test_resolve_ymaa_strict($y, $m, $w, $d, $expected, $smar, $strict) { $fieldValues = new FieldValues(); $fieldValues->put(ChronoField::YEAR(), $y); $fieldValues->put(ChronoField::MONTH_OF_YEAR(), $m); $fieldValues->put(ChronoField::ALIGNED_WEEK_OF_MONTH(), $w); $fieldValues->put(ChronoField::ALIGNED_DAY_OF_WEEK_IN_MONTH(), $d); if ($strict) { $date = IsoChronology::INSTANCE()->resolveDate($fieldValues, ResolverStyle::STRICT()); $this->assertEquals($date, $expected); $this->assertEquals($fieldValues->size(), 0); } else { try { IsoChronology::INSTANCE()->resolveDate($fieldValues, ResolverStyle::STRICT()); $this->fail("Should have failed"); } catch (DateTimeException $ex) { // $expected } } }
public function setUp() { // slight abuse of FieldValues $this->fieldMap = new FieldValues(); $this->fieldMap->put(ChronoField::ERA(), "era"); $this->fieldMap->put(ChronoField::YEAR(), "year"); $this->fieldMap->put(ChronoField::MONTH_OF_YEAR(), "month"); $this->fieldMap->put(ChronoField::DAY_OF_MONTH(), "day"); $this->fieldMap->put(ChronoField::AMPM_OF_DAY(), "dayperiod"); $this->fieldMap->put(ChronoField::ALIGNED_WEEK_OF_YEAR(), "week"); $this->fieldMap->put(ChronoField::DAY_OF_WEEK(), "weekday"); $this->fieldMap->put(ChronoField::HOUR_OF_DAY(), "hour"); $this->fieldMap->put(ChronoField::MINUTE_OF_HOUR(), "minute"); $this->fieldMap->put(ChronoField::SECOND_OF_MINUTE(), "second"); $this->fieldMap->put(ChronoField::OFFSET_SECONDS(), "zone"); }
public function resolve(FieldValues $fieldValues, TemporalAccessor $partialTemporal, ResolverStyle $resolverStyle) { $fieldValues->remove($this); return $this->resolvedValue; }
private function resolveWBY(FieldValues $fieldValues, Chronology $chrono, $localDow, ResolverStyle $resolverStyle) { $yowby = $this->weekDef->weekBasedYear->range()->checkValidIntValue($fieldValues->get($this->weekDef->weekBasedYear), $this->weekDef->weekBasedYear); if ($resolverStyle == ResolverStyle::LENIENT()) { $date = $this->ofWeekBasedYear($chrono, $yowby, 1, $localDow); $wowby = $fieldValues->get($this->weekDef->weekOfWeekBasedYear); $weeks = Math::subtractExact($wowby, 1); $date = $date->plus($weeks, ChronoUnit::WEEKS()); } else { $wowby = $this->weekDef->weekOfWeekBasedYear->range()->checkValidIntValue($fieldValues->get($this->weekDef->weekOfWeekBasedYear), $this->weekDef->weekOfWeekBasedYear); // validate $date = $this->ofWeekBasedYear($chrono, $yowby, $wowby, $localDow); if ($resolverStyle == ResolverStyle::STRICT() && $this->localizedWeekBasedYear($date) != $yowby) { throw new DateTimeException("Strict mode rejected resolved date as it is in a different week-based-year"); } } $fieldValues->remove($this); $fieldValues->remove($this->weekDef->weekBasedYear); $fieldValues->remove($this->weekDef->weekOfWeekBasedYear); $fieldValues->remove(CF::DAY_OF_WEEK()); return $date; }
public function getLong(TemporalField $field) { $val = $this->fields->get($field); if ($val === null) { throw new DateTimeException("Field missing: " . $field); } return $val; }