/** * Returns a zoned date-time from this date at the earliest valid time according * to the rules in the time-zone. * <p> * Time-zone rules, such as daylight savings, mean that not every local date-time * is valid for the specified zone, thus the local date-time may not be midnight. * <p> * In most cases, there is only one valid offset for a local date-time. * In the case of an overlap, there are two valid offsets, and the earlier one is used, * corresponding to the first occurrence of midnight on the date. * In the case of a gap, the zoned date-time will represent the instant just after the gap. * <p> * If the zone ID is a {@link ZoneOffset}, then the result always has a time of midnight. * <p> * To convert to a specific time in a given time-zone call {@link #atTime(LocalTime)} * followed by {@link LocalDateTime#atZone(ZoneId)}. * * @param ZoneId $zone the zone ID to use, not null * @return ZonedDateTime the zoned date-time formed from this date and the earliest valid time for the zone, not null */ public function atStartOfDayWithZone(ZoneId $zone) { // need to handle case where there is a gap from 11:30 to 00:30 // standard ZDT factory would result in 01:00 rather than 00:30 $ldt = $this->atTime(LocalTime::MIDNIGHT()); if ($zone instanceof ZoneOffset === false) { $rules = $zone->getRules(); $trans = $rules->getTransition($ldt); if ($trans != null && $trans->isGap()) { $ldt = $trans->getDateTimeAfter(); } } return ZonedDateTime::ofDateTime($ldt, $zone); }
/** * Obtains an instance of {@code OffsetDateTime} from an {@code Instant} and zone ID. * <p> * This creates an offset date-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. * * @param Instant $instant the instant to create the date-time from, not null * @param ZoneId $zone the time-zone, which may be an offset, not null * @return OffsetDateTime the offset date-time, not null * @throws DateTimeException if the result exceeds the supported range */ public static function ofInstant(Instant $instant, ZoneId $zone) { $rules = $zone->getRules(); $offset = $rules->getOffset($instant); $ldt = LocalDateTime::ofEpochSecond($instant->getEpochSecond(), $instant->getNano(), $offset); return new OffsetDateTime($ldt, $offset); }
/** * @dataProvider provider_sampleTimes */ public function test_get($y, $o, $d, $h, $m, $s, $n, ZoneId $zone) { $localDate = LocalDate::of($y, $o, $d); $localTime = LocalTime::of($h, $m, $s, $n); $localDateTime = LocalDateTime::ofDateAndTime($localDate, $localTime); $offset = $zone->getRules()->getOffsetDateTime($localDateTime); $a = ZonedDateTime::ofDateTime($localDateTime, $zone); $this->assertEquals($a->getYear(), $localDate->getYear()); $this->assertEquals($a->getMonth(), $localDate->getMonth()); $this->assertEquals($a->getDayOfMonth(), $localDate->getDayOfMonth()); $this->assertEquals($a->getDayOfYear(), $localDate->getDayOfYear()); $this->assertEquals($a->getDayOfWeek(), $localDate->getDayOfWeek()); $this->assertEquals($a->getHour(), $localTime->getHour()); $this->assertEquals($a->getMinute(), $localTime->getMinute()); $this->assertEquals($a->getSecond(), $localTime->getSecond()); $this->assertEquals($a->getNano(), $localTime->getNano()); $this->assertEquals($a->toLocalDate(), $localDate); $this->assertEquals($a->toLocalTime(), $localTime); $this->assertEquals($a->toLocalDateTime(), $localDateTime); if ($zone instanceof ZoneOffset) { $this->assertEquals($a->__toString(), $localDateTime->__toString() . $offset->__toString()); } else { $this->assertEquals($a->__toString(), $localDateTime->__toString() . $offset->__toString() . "[" . $zone->__toString() . "]"); } }
/** * Obtains an instance from an instant using the specified time-zone. * * @param Chronology $chrono the chronology, not null * @param Instant $instant the instant, not null * @param ZoneId $zone the zone identifier, not null * @return ChronoZonedDateTimeImpl the zoned date-time, not null */ static function ofInstant(Chronology $chrono, Instant $instant, ZoneId $zone) { $rules = $zone->getRules(); $offset = $rules->getOffset($instant); // TODO Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules $ldt = LocalDateTime::ofEpochSecond($instant->getEpochSecond(), $instant->getNano(), $offset); $cldt = $chrono->localDateTime($ldt); return new ChronoZonedDateTimeImpl($cldt, $offset, $zone); }
/** * Obtains an instance of {@code LocalDateTime} from an {@code Instant} and zone ID. * <p> * This creates a local date-time based on the specified instant. * First, the offset from UTC/Greenwich is obtained using the zone ID and instant, * which is simple as there is only one valid offset for each instant. * Then, the instant and offset are used to calculate the local date-time. * * @param Instant $instant the instant to create the date-time from, not null * @param ZoneId $zone the time-zone, which may be an offset, not null * @return LocalDateTime the local date-time, not null * @throws DateTimeException if the result exceeds the supported range */ public static function ofInstant(Instant $instant, ZoneId $zone) { $rules = $zone->getRules(); $offset = $rules->getOffset($instant); return self::ofEpochSecond($instant->getEpochSecond(), $instant->getNano(), $offset); }
/** * Resolves the offset into this zoned date-time for the with methods. * <p> * This typically ignores the offset, unless it can be used to switch offset in a DST overlap. * * @param ZoneOffset $offset the offset, not null * @return ZonedDateTime the zoned date-time, not null */ private function resolveOffset(ZoneOffset $offset) { if ($offset->equals($this->offset) == false && $this->zone->getRules()->isValidOffset($this->dateTime, $offset)) { return new ZonedDateTime($this->dateTime, $offset, $this->zone); } return $this; }
/** * 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); }