Example #1
0
 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);
 }
Example #2
0
 private function secondsUntil(Instant $end)
 {
     $secsDiff = Math::subtractExact($end->seconds, $this->seconds);
     $nanosDiff = $end->nanos - $this->nanos;
     if ($secsDiff > 0 && $nanosDiff < 0) {
         $secsDiff--;
     } else {
         if ($secsDiff < 0 && $nanosDiff > 0) {
             $secsDiff++;
         }
     }
     return $secsDiff;
 }
 protected function resolveAligned(ChronoLocalDate $base, $months, $weeks, $dow)
 {
     $date = $base->plus($months, ChronoUnit::MONTHS())->plus($weeks, ChronoUnit::WEEKS());
     if ($dow > 7) {
         $date = $date->plus(($dow - 1) / 7, ChronoUnit::WEEKS());
         $dow = ($dow - 1) % 7 + 1;
     } else {
         if ($dow < 1) {
             $date = $date->plus(Math::subtractExact($dow, 7) / 7, ChronoUnit::WEEKS());
             $dow = ($dow + 6) % 7 + 1;
         }
     }
     return $date->adjust(TemporalAdjusters::nextOrSame(DayOfWeek::of((int) $dow)));
 }
 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;
 }
Example #5
0
 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);
 }
 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;
 }
Example #7
0
 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);
 }
Example #8
0
 public function between(Temporal $temporal1Inclusive, Temporal $temporal2Exclusive)
 {
     if (get_class($temporal1Inclusive) !== get_class($temporal2Exclusive)) {
         return $temporal1Inclusive->until($temporal2Exclusive, $this);
     }
     switch ($this) {
         case self::WEEK_BASED_YEARS():
             return Math::subtractExact($temporal2Exclusive->getLong(IsoFields::WEEK_BASED_YEAR()), $temporal1Inclusive->getLong(IsoFields::WEEK_BASED_YEAR()));
         case self::QUARTER_YEARS():
             return Math::div($temporal1Inclusive->until($temporal2Exclusive, ChronoUnit::MONTHS()), 3);
         default:
             throw new IllegalStateException("Unreachable");
     }
 }
Example #9
0
 /**
  * Returns a copy of this period with the specified period subtracted.
  * <p>
  * This operates separately on the years, months and days.
  * No normalization is performed.
  * <p>
  * For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days"
  * returns "-1 years, 4 months and 1 day".
  * <p>
  * The specified amount is typically an instance of {@code Period}.
  * Other types are interpreted using {@link Period#from(TemporalAmount)}.
  * <p>
  * This instance is immutable and unaffected by this method call.
  *
  * @param TemporalAmount $amountToSubtract the amount to subtract, not null
  * @return Period a {@code Period} based on this period with the requested period subtracted, not null
  * @throws DateTimeException if the specified amount has a non-ISO chronology or
  *  contains an invalid unit
  * @throws ArithmeticException if numeric overflow occurs
  */
 public function minusAmount(TemporalAmount $amountToSubtract)
 {
     $isoAmount = Period::from($amountToSubtract);
     return $this->create(Math::subtractExact($this->years, $isoAmount->years), Math::subtractExact($this->months, $isoAmount->months), Math::subtractExact($this->days, $isoAmount->days));
 }