/** * @param \DateTime|string|float $input The date or a string the DateTime c'tor can understand or a timestamp * @param \DateTimeZone|string $timezone The timezone or a string the DateTimeZone c'tor can understand */ public function __construct($input, $timezone) { if (!$timezone instanceof \DateTimeZone) { $timezone = new \DateTimeZone((string) $timezone); } ///// // We have to trick PHP a bit here, but why? // // Apparently things behave different, when setting a timezone like // a) 'Europe/Berlin' // b) '+02:00' // // When the date already has a timezone set then // a) will only set the timezone // b) will set the timezone and will also change the timestamp by 2 hours // // Therefore we create a fresh date, that does not have a timezone yet, set the timestamp, and then apply the // timezone // // See the unit tests for more as well //// if ($input instanceof \DateTime) { $date = (new \DateTime())->setTimestamp($input->getTimestamp())->setTimezone($timezone); } elseif (is_numeric($input)) { $date = (new \DateTime())->setTimestamp($input)->setTimezone($timezone); } else { // when we have string input, we immediately use the timezone $tmp = new \DateTime($input, $timezone); // we reconstruct the date time again in order to set the timezone on the inner one $date = (new \DateTime())->setTimestamp($tmp->getTimestamp())->setTimezone($timezone); } $this->date = $date; $this->timezone = $timezone; }