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);
     }
 }
Exemple #6
0
 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;
 }