/** * A query for {@code LocalTime} returning null if not found. * @param TemporalAccessor $temporal * @return null|LocalTime */ public static function _localTime(TemporalAccessor $temporal) { if ($temporal->isSupported(ChronoField::NANO_OF_DAY())) { return LocalTime::ofNanoOfDay($temporal->getLong(ChronoField::NANO_OF_DAY())); } return null; }
private function resolveTime($hod, $moh, $som, $nos) { if ($this->resolverStyle == ResolverStyle::LENIENT()) { $totalNanos = Math::multiplyExact($hod, 3600000000000); $totalNanos = Math::addExact($totalNanos, Math::multiplyExact($moh, 60000000000)); $totalNanos = Math::addExact($totalNanos, Math::multiplyExact($som, 1000000000)); $totalNanos = Math::addExact($totalNanos, $nos); $excessDays = (int) Math::floorDiv($totalNanos, 86400000000000); // safe int cast $nod = Math::floorMod($totalNanos, 86400000000000); $this->updateCheckConflict(LocalTime::ofNanoOfDay($nod), Period::ofDays($excessDays)); } else { // STRICT or SMART $mohVal = CF::MINUTE_OF_HOUR()->checkValidIntValue($moh); $nosVal = CF::NANO_OF_SECOND()->checkValidIntValue($nos); // handle 24:00 end of day if ($this->resolverStyle == ResolverStyle::SMART() && $hod == 24 && $mohVal == 0 && $som == 0 && $nosVal == 0) { $this->updateCheckConflict(LocalTime::MIDNIGHT(), Period::ofDays(1)); } else { $hodVal = CF::HOUR_OF_DAY()->checkValidIntValue($hod); $somVal = CF::SECOND_OF_MINUTE()->checkValidIntValue($som); $this->updateCheckConflict(LocalTime::of($hodVal, $mohVal, $somVal, $nosVal), Period::ZERO()); } } }
/** * @group long */ public function test_toNanoOfDay_fromNanoOfDay_symmetry() { $t = LocalTime::of(0, 0); for ($i = 0; $i < 1000000; $i++) { $this->assertEquals(LocalTime::ofNanoOfDay($t->toNanoOfDay()), $t); $t = $t->plusNanos(1); } $t = LocalTime::of(0, 0); for ($i = 1; $i <= 1000000; $i++) { $t = $t->minusNanos(1); $this->assertEquals(LocalTime::ofNanoOfDay($t->toNanoOfDay()), $t); } }
/** * Returns a copy of this {@code LocalDateTime} with the specified period added. * <p> * This instance is immutable and unaffected by this method call. * * @param LocalDate $newDate the new date to base the calculation on, not null * @param int $hours the hours to add, may be negative * @param int $minutes the minutes to add, may be negative * @param int $seconds the seconds to add, may be negative * @param int $nanos the nanos to add, may be negative * @param int $sign the sign to determine add or subtract * @return LocalDateTime the combined result, not null */ private function plusWithOverflow(LocalDate $newDate, $hours, $minutes, $seconds, $nanos, $sign) { // 9223372036854775808 long, 2147483648 int if (($hours | $minutes | $seconds | $nanos) == 0) { return $this->_with($newDate, $this->time); } $totDays = Math::div($nanos, LocalTime::NANOS_PER_DAY) + Math::div($seconds, LocalTime::SECONDS_PER_DAY) + Math::div($minutes, LocalTime::MINUTES_PER_DAY) + Math::div($hours, LocalTime::HOURS_PER_DAY); // max/24 $totDays *= $sign; // total max*0.4237... $totNanos = $nanos % LocalTime::NANOS_PER_DAY + $seconds % LocalTime::SECONDS_PER_DAY * LocalTime::NANOS_PER_SECOND + $minutes % LocalTime::MINUTES_PER_DAY * LocalTime::NANOS_PER_MINUTE + $hours % LocalTime::HOURS_PER_DAY * LocalTime::NANOS_PER_HOUR; // max 86400000000000 $curNoD = $this->time->toNanoOfDay(); // max 86400000000000 $totNanos = $totNanos * $sign + $curNoD; // total 432000000000000 $totDays += Math::floorDiv($totNanos, LocalTime::NANOS_PER_DAY); $newNoD = Math::floorMod($totNanos, LocalTime::NANOS_PER_DAY); $newTime = $newNoD === $curNoD ? $this->time : LocalTime::ofNanoOfDay($newNoD); return $this->_with($newDate->plusDays($totDays), $newTime); }
/** * Obtains an instance of {@code OffsetTime} from an {@code Instant} and zone ID. * <p> * This creates an offset time with the same instant as that specified. * Finding the offset from UTC/Greenwich is simple as there is only one valid * offset for each instant. * <p> * The date component of the instant is dropped during the conversion. * This means that the conversion can never fail due to the instant being * out of the valid range of dates. * * @param Instant $instant the instant to create the time from, not null * @param ZoneId $zone the time-zone, which may be an offset, not null * @return OffsetTime the offset time, not null */ public static function ofInstant(Instant $instant, ZoneId $zone) { $rules = $zone->getRules(); $offset = $rules->getOffset($instant); $localSecond = $instant->getEpochSecond() + $offset->getTotalSeconds(); // overflow caught later $secsOfDay = (int) Math::floorMod($localSecond, LocalTime::SECONDS_PER_DAY); $time = LocalTime::ofNanoOfDay($secsOfDay * LocalTime::NANOS_PER_SECOND + $instant->getNano()); return new OffsetTime($time, $offset); }