/** * Converts the specified local date-time to the local date-time actually * seen on a wall clock. * <p> * This method converts using the type of this enum. * The output is defined relative to the 'before' offset of the transition. * <p> * The UTC type uses the UTC offset. * The STANDARD type uses the standard offset. * The WALL type returns the input date-time. * The result is intended for use with the wall-offset. * * @param LocalDateTime $dateTime the local date-time, not null * @param ZoneOffset $standardOffset the standard offset, not null * @param ZoneOffset $wallOffset the wall offset, not null * @return LocalDateTime the date-time relative to the wall/before offset, not null */ public function createDateTime(LocalDateTime $dateTime, ZoneOffset $standardOffset, ZoneOffset $wallOffset) { switch ($this->val) { case 0: $difference = $wallOffset->getTotalSeconds() - ZoneOffset::UTC()->getTotalSeconds(); return $dateTime->plusSeconds($difference); case 2: $difference = $wallOffset->getTotalSeconds() - $standardOffset->getTotalSeconds(); return $dateTime->plusSeconds($difference); default: // WALL return $dateTime; } }
/** * Converts this to a transition. * * @param ZoneOffset $standardOffset the active standard offset, not null * @param int $savingsBeforeSecs the active savings in seconds * @return ZoneOffsetTransition the transition, not null */ function toTransition(ZoneOffset $standardOffset, $savingsBeforeSecs) { // copy of code in ZoneOffsetTransitionRule to avoid infinite loop $date = $this->toLocalDate(); $date = ZoneRulesBuilder::deduplicate($date); $ldt = ZoneRulesBuilder::deduplicate(LocalDateTime::ofDateAndTime($date, $this->time)); /** @var ZoneOffset $wallOffset */ $wallOffset = ZoneRulesBuilder::deduplicate(ZoneOffset::ofTotalSeconds($standardOffset->getTotalSeconds() + $savingsBeforeSecs)); $dt = ZoneRulesBuilder::deduplicate($this->timeDefinition->createDateTime($ldt, $standardOffset, $wallOffset)); $offsetAfter = ZoneRulesBuilder::deduplicate(ZoneOffset::ofTotalSeconds($standardOffset->getTotalSeconds() + $this->savingAmountSecs)); return new ZoneOffsetTransition($dt, $wallOffset, $offsetAfter); }
private function doTestOffset(ZoneOffset $offset, $hours, $minutes, $seconds) { $this->assertEquals($offset->getTotalSeconds(), $hours * 60 * 60 + $minutes * 60 + $seconds); if ($hours == 0 && $minutes == 0 && $seconds == 0) { $id = "Z"; } else { $str = $hours < 0 || $minutes < 0 || $seconds < 0 ? "-" : "+"; $str .= substr(Math::abs($hours) + 100, 1); $str .= ":"; $str .= substr(Math::abs($minutes) + 100, 1); if ($seconds != 0) { $str .= ":"; $str .= substr(Math::abs($seconds) + 100, 1); } $id = $str; } $this->assertEquals($offset->getId(), $id); $this->assertEquals($offset, ZoneOffset::ofHoursMinutesSeconds($hours, $minutes, $seconds)); if ($seconds == 0) { $this->assertEquals($offset, ZoneOffset::ofHoursMinutes($hours, $minutes)); if ($minutes == 0) { $this->assertEquals($offset, ZoneOffset::ofHours($hours)); } } $this->assertEquals(ZoneOffset::of($id), $offset); $this->assertEquals($offset->__toString(), $id); }
/** * Returns a copy of this {@code OffsetDateTime} with the specified offset ensuring * that the result is at the same instant. * <p> * This method returns an object with the specified {@code ZoneOffset} and a {@code LocalDateTime} * adjusted by the difference between the two offsets. * This will result in the old and new objects representing the same instant. * This is useful for finding the local time in a different offset. * For example, if this time represents {@code 2007-12-03T10:30+02:00} and the offset specified is * {@code +03:00}, then this method will return {@code 2007-12-03T11:30+03:00}. * <p> * To change the offset without adjusting the local time use {@link #withOffsetSameLocal}. * <p> * This instance is immutable and unaffected by this method call. * * @param ZoneOffset $offset the zone offset to change to, not null * @return OffsetDateTime an {@code OffsetDateTime} based on this date-time with the requested offset, not null * @throws DateTimeException if the result exceeds the supported date range */ public function withOffsetSameInstant(ZoneOffset $offset) { if ($offset->equals($this->offset)) { return $this; } $difference = $offset->getTotalSeconds() - $this->offset->getTotalSeconds(); $adjusted = $this->dateTime->plusSeconds($difference); return new OffsetDateTime($adjusted, $offset); }
private function assertParsed(TemporalAccessor $parsed, ZoneOffset $expectedOffset) { if ($expectedOffset === null) { $this->assertEquals(null, $parsed); } else { $this->assertEquals(true, $parsed->isSupported(ChronoField::OFFSET_SECONDS()), true); $this->assertEquals($expectedOffset->getTotalSeconds(), $parsed->getLong(ChronoField::OFFSET_SECONDS())); } }
/** * Creates the wall offset for the local date-time at the end of the window. * * @param int $savingsSecs the amount of savings in use in seconds * @return ZoneOffset the created date-time epoch second in the wall offset, not null */ function createWallOffset($savingsSecs) { return ZoneOffset::ofTotalSeconds($this->standardOffset->getTotalSeconds() + $savingsSecs); }
/** * Obtains an instance of {@code ZoneId} wrapping an offset. * <p> * If the prefix is "GMT", "UTC", or "UT" a {@code ZoneId} * with the prefix and the non-zero offset is returned. * If the prefix is empty {@code ""} the {@code ZoneOffset} is returned. * * @param string $prefix the time-zone ID, not null * @param ZoneOffset $offset the offset, not null * @return ZoneId the zone ID, not null * @throws IllegalArgumentException if the prefix is not one of * "GMT", "UTC", or "UT", or "" */ public static function ofOffset($prefix, ZoneOffset $offset) { if (!is_string($prefix)) { throw new \InvalidArgumentException(); } if (strlen($prefix) === 0) { return $offset; } if ($prefix !== "GMT" && $prefix !== "UTC" && $prefix !== "UT") { throw new IllegalArgumentException("prefix should be GMT, UTC or UT, is: " . $prefix); } if ($offset->getTotalSeconds() !== 0) { $prefix .= $offset->getId(); } return new ZoneRegion($prefix, $offset->getRules()); }
private function findYear($epochSecond, ZoneOffset $offset) { // inline for performance $localSecond = $epochSecond + $offset->getTotalSeconds(); $localEpochDay = Math::floorDiv($localSecond, 86400); return LocalDate::ofEpochDay($localEpochDay)->getYear(); }
/** * Obtains an instance of {@code LocalDateTime} using seconds from the * epoch of 1970-01-01T00:00:00Z. * <p> * This allows the {@link ChronoField#INSTANT_SECONDS epoch-second} field * to be converted to a local date-time. This is primarily intended for * low-level conversions rather than general application usage. * * @param int $epochSecond the number of seconds from the epoch of 1970-01-01T00:00:00Z * @param int $nanoOfSecond the nanosecond within the second, from 0 to 999,999,999 * @param ZoneOffset $offset the zone offset, not null * @return LocalDateTime the local date-time, not null * @throws DateTimeException if the result exceeds the supported range, * or if the nano-of-second is invalid */ public static function ofEpochSecond($epochSecond, $nanoOfSecond, ZoneOffset $offset) { try { ChronoField::NANO_OF_SECOND()->checkValidValue($nanoOfSecond); $localSecond = Math::addExact($epochSecond, $offset->getTotalSeconds()); $localEpochDay = Math::floorDiv($localSecond, LocalTime::SECONDS_PER_DAY); $secsOfDay = Math::floorMod($localSecond, LocalTime::SECONDS_PER_DAY); $date = LocalDate::ofEpochDay($localEpochDay); $time = LocalTime::ofNanoOfDay($secsOfDay * LocalTime::NANOS_PER_SECOND + $nanoOfSecond); return new LocalDateTime($date, $time); } catch (ArithmeticException $ex) { throw new DateTimeException("Value out of bounds", $ex); } }
/** * @inheritdoc */ public function toEpochSecond(ZoneOffset $offset) { $epochDay = $this->toLocalDate()->toEpochDay(); $secs = $epochDay * 86400 + $this->toLocalTime()->toSecondOfDay(); $secs -= $offset->getTotalSeconds(); return $secs; }
function add(ZoneOffset $offset) { $this->fieldValues->put(ChronoField::OFFSET_SECONDS(), $offset->getTotalSeconds()); }
/** * Converts this time to epoch nanos based on 1970-01-01Z. * * @return int the epoch nanos value */ private function toEpochNano() { $nod = $this->time->toNanoOfDay(); $offsetNanos = $this->offset->getTotalSeconds() * LocalTime::NANOS_PER_SECOND; return $nod - $offsetNanos; }