src/ZonedDateTime.php
public static function of(LocalDateTime $dateTime, TimeZone $timeZone) : ZonedDateTime
    {
        $dtz = $timeZone->toDateTimeZone();
        $dt = new \DateTime((string) $dateTime->withNano(0), $dtz);

        $instant = Instant::of($dt->getTimestamp(), $dateTime->getNano());

        if ($timeZone instanceof TimeZoneOffset) {
            $timeZoneOffset = $timeZone;
        } else {
            $timeZoneOffset = TimeZoneOffset::ofTotalSeconds($dt->getOffset());
        }

        // The time can be affected if the date-time is not valid for the given time-zone due to a DST transition,
        // so we have to re-compute the local date-time from the DateTime object.
        // DateTime does not support nanos of seconds, so we just copy the nanos back from the original date-time.
        $dateTime = LocalDateTime::parse($dt->format('Y-m-d\TH:i:s'))->withNano($dateTime->getNano());

        return new ZonedDateTime($dateTime, $timeZoneOffset, $timeZone, $instant);
    }
public static function of(LocalDateTime $dateTime, TimeZone $timeZone) : ZonedDateTime
    {
        $dtz = $timeZone->toDateTimeZone();
        $dt = new \DateTime((string) $dateTime->withNano(0), $dtz);

        $instant = Instant::of($dt->getTimestamp(), $dateTime->getNano());

        if ($timeZone instanceof TimeZoneOffset) {
            $timeZoneOffset = $timeZone;
        } else {
            $timeZoneOffset = TimeZoneOffset::ofTotalSeconds($dt->getOffset());
        }

        // The time can be affected if the date-time is not valid for the given time-zone due to a DST transition,
        // so we have to re-compute the local date-time from the DateTime object.
        // DateTime does not support nanos of seconds, so we just copy the nanos back from the original date-time.
        $dateTime = LocalDateTime::parse($dt->format('Y-m-d\TH:i:s'))->withNano($dateTime->getNano());

        return new ZonedDateTime($dateTime, $timeZoneOffset, $timeZone, $instant);
    }
public static function of ( LocalDateTime $ dateTime , TimeZone $ timeZone ) : ZonedDateTime { $ dtz = $ timeZone -> toDateTimeZone ( ) ; $ dt = new \ DateTime ( ( string ) $ dateTime -> withNano ( 0 ) , $ dtz ) ; $ instant = Instant :: of ( $ dt -> getTimestamp ( ) , $ dateTime -> getNano ( ) ) ; if ( $ timeZone instanceof TimeZoneOffset ) { $ timeZoneOffset = $ timeZone ; } else { $ timeZoneOffset = TimeZoneOffset :: ofTotalSeconds ( $ dt -> getOffset ( ) ) ; } // The time can be affected if the date-time is not valid for the given time-zone due to a DST transition, // so we have to re-compute the local date-time from the DateTime object. // DateTime does not support nanos of seconds, so we just copy the nanos back from the original date-time. $ dateTime = LocalDateTime :: parse ( $ dt -> format ( 'Y-m-d\TH:i:s' ) ) -> withNano ( $ dateTime -> getNano ( ) ) ; return new ZonedDateTime ( $ dateTime , $ timeZoneOffset , $ timeZone , $ instant ) ; }
Creates a ZonedDateTime from a LocalDateTime and a TimeZone.

This resolves the local date-time to an instant on the time-line.

When a TimeZoneOffset is used, the local date-time can be converted to an instant without ambiguity.

When a TimeZoneRegion is used, Daylight Saving Time can make the conversion more complex.
There are 3 cases:

- Normal: when there is only one valid offset for the date-time. The conversion is then as straightforward
as when using a TimeZoneOffset. This is fortunately the case for the vast majority of the year.
- Gap: when there is no valid offset for the date-time. This happens when the clock jumps forward
typically due to a DST transition from "winter" to "summer". The date-times between the two times
of the transition do not exist.
- Overlap: when there are two valid offets for the date-time. This happens when the clock is set back
typically due to a DST transition from "summer" to "winter". The date-times between the two times
of the transition can be resolved to two different offsets, representing two different instants
on the time-line.

The strategy for resolving gaps and overlaps is the following:

- If the local date-time falls in the middle of a gap, then the resulting date-time will be shifted forward
by the length of the gap, and the later offset, typically "summer" time, will be used.
- If the local date-time falls in the middle of an overlap, then the offset closest to UTC will be used.

@param LocalDateTime $dateTime
@param TimeZone      timeZone

@return ZonedDateTime
Creates a ZonedDateTime from a LocalDateTime and a TimeZone .