timeZoneOffset = static::extractDateTimeZone($timezone); } private static function extractDateTimeZone(string|int|float|null $timezone): \DateTimeZone { if ($timezone === null) { return new \DateTimeZone(date_default_timezone_get()); } if (is_int($timezone)) { if ($timezone < -12 || $timezone > 14) { throw new \InvalidArgumentException('TimeZone argument must be between -12 and 14'); } if ($timezone > 0) { $offset = sprintf('+%02d00', $timezone); } else { $offset = sprintf('-%02d00', abs($timezone)); } return new \DateTimeZone($offset); } if (is_float($timezone)) { if ($timezone < -12 || $timezone > 14) { throw new \InvalidArgumentException('TimeZone argument must be between -12 and 14'); } $isPositive = $timezone > 0; $offset = abs($timezone); $hour = floor($offset); $minute = floor(($offset - $hour) * 60); if ($isPositive) { $offset = sprintf('+%02d%02d', $hour, $minute); } else { $offset = sprintf('-%02d%02d', $hour, $minute); } return new \DateTimeZone($offset); } return new \DateTimeZone($timezone); } public function convertFrom(string|array|int|float|bool|null $raw): mixed { if ($raw === null && array_search('null', $this->types, true) !== false) { return null; } if (!is_string($raw)) { throw new \InvalidArgumentException('DateTimeConverter can not convert non-string'); } if (array_search('DateTimeImmutable', $this->types, true) !== false) { $objDateTime = new \DateTimeImmutable($raw, $this->timeZoneOffset); } else if (array_search('DateTime', $this->types, true) !== false) { $objDateTime = new \DateTime($raw, $this->timeZoneOffset); } else { $objDateTime = new \DateTimeImmutable($raw, $this->timeZoneOffset); } if ($objDateTime->getTimezone() !== $this->timeZoneOffset) { $objDateTime = $objDateTime->setTimezone($this->timeZoneOffset); } return $objDateTime; } public function convertTo(mixed $data): string|array|int|float|bool|null { if ($data === null && array_search('null', $this->types, true) !== false) { return null; } if (!$data instanceof \DateTimeInterface) { throw new \Exception('DateTimeConverter can not convert non-DateTimeInterface'); } if ($data->getTimezone() !== $this->timeZoneOffset) { $data = \DateTimeImmutable::createFromInterface($data)->setTimezone($this->timeZoneOffset); } return $data->format($this->datetimeFormat); } }