Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
232
src/Framework/Core/ValueObjects/Timezone.php
Normal file
232
src/Framework/Core/ValueObjects/Timezone.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Core\ValueObjects;
|
||||
|
||||
use DateTimeZone;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Timezone value object
|
||||
*/
|
||||
final readonly class Timezone
|
||||
{
|
||||
public function __construct(
|
||||
public string $value
|
||||
) {
|
||||
$this->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from timezone string
|
||||
*/
|
||||
public static function fromString(string $timezone): self
|
||||
{
|
||||
return new self($timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create UTC timezone
|
||||
*/
|
||||
public static function utc(): self
|
||||
{
|
||||
return new self('UTC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create timezone for Europe/Berlin
|
||||
*/
|
||||
public static function berlin(): self
|
||||
{
|
||||
return new self('Europe/Berlin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create timezone for America/New_York
|
||||
*/
|
||||
public static function newYork(): self
|
||||
{
|
||||
return new self('America/New_York');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create timezone for Asia/Tokyo
|
||||
*/
|
||||
public static function tokyo(): self
|
||||
{
|
||||
return new self('Asia/Tokyo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DateTimeZone object
|
||||
*/
|
||||
public function toDateTimeZone(): DateTimeZone
|
||||
{
|
||||
return new DateTimeZone($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone offset in seconds from UTC
|
||||
*/
|
||||
public function getOffsetFromUtc(): int
|
||||
{
|
||||
$timezone = $this->toDateTimeZone();
|
||||
$now = new \DateTime('now', $timezone);
|
||||
|
||||
return $timezone->getOffset($now);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone offset as string (+/-HH:MM)
|
||||
*/
|
||||
public function getOffsetString(): string
|
||||
{
|
||||
$offset = $this->getOffsetFromUtc();
|
||||
$hours = intval($offset / 3600);
|
||||
$minutes = abs(intval(($offset % 3600) / 60));
|
||||
|
||||
return sprintf('%+03d:%02d', $hours, $minutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if timezone is UTC
|
||||
*/
|
||||
public function isUtc(): bool
|
||||
{
|
||||
return $this->value === 'UTC';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if timezone uses daylight saving time
|
||||
*/
|
||||
public function usesDaylightSaving(): bool
|
||||
{
|
||||
$timezone = $this->toDateTimeZone();
|
||||
$transitions = $timezone->getTransitions();
|
||||
|
||||
// If there are transitions, it likely uses DST
|
||||
return count($transitions) > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone name
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone abbreviation
|
||||
*/
|
||||
public function getAbbreviation(): string
|
||||
{
|
||||
$timezone = $this->toDateTimeZone();
|
||||
$now = new \DateTime('now', $timezone);
|
||||
|
||||
return $now->format('T');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get continent
|
||||
*/
|
||||
public function getContinent(): ?string
|
||||
{
|
||||
$parts = explode('/', $this->value);
|
||||
|
||||
return $parts[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get city/region
|
||||
*/
|
||||
public function getCity(): ?string
|
||||
{
|
||||
$parts = explode('/', $this->value);
|
||||
|
||||
return $parts[1] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a valid timezone for geographic region
|
||||
*/
|
||||
public function isValidForCountry(CountryCode $countryCode): bool
|
||||
{
|
||||
$countryTimezones = [
|
||||
'DE' => ['Europe/Berlin'],
|
||||
'US' => [
|
||||
'America/New_York', 'America/Chicago', 'America/Denver',
|
||||
'America/Los_Angeles', 'America/Anchorage', 'Pacific/Honolulu',
|
||||
],
|
||||
'GB' => ['Europe/London'],
|
||||
'FR' => ['Europe/Paris'],
|
||||
'JP' => ['Asia/Tokyo'],
|
||||
'CN' => ['Asia/Shanghai'],
|
||||
'IN' => ['Asia/Kolkata'],
|
||||
'RU' => [
|
||||
'Europe/Moscow', 'Asia/Yekaterinburg', 'Asia/Novosibirsk',
|
||||
'Asia/Krasnoyarsk', 'Asia/Irkutsk', 'Asia/Yakutsk',
|
||||
'Asia/Vladivostok', 'Asia/Magadan', 'Asia/Kamchatka',
|
||||
],
|
||||
'AU' => [
|
||||
'Australia/Sydney', 'Australia/Melbourne', 'Australia/Brisbane',
|
||||
'Australia/Perth', 'Australia/Adelaide', 'Australia/Darwin',
|
||||
],
|
||||
'BR' => [
|
||||
'America/Sao_Paulo', 'America/Manaus', 'America/Fortaleza',
|
||||
'America/Recife', 'America/Bahia',
|
||||
],
|
||||
'CA' => [
|
||||
'America/Toronto', 'America/Vancouver', 'America/Montreal',
|
||||
'America/Calgary', 'America/Edmonton', 'America/Winnipeg',
|
||||
],
|
||||
];
|
||||
|
||||
$validTimezones = $countryTimezones[$countryCode->value] ?? [];
|
||||
|
||||
return in_array($this->value, $validTimezones, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'timezone' => $this->value,
|
||||
'offset' => $this->getOffsetString(),
|
||||
'offset_seconds' => $this->getOffsetFromUtc(),
|
||||
'abbreviation' => $this->getAbbreviation(),
|
||||
'continent' => $this->getContinent(),
|
||||
'city' => $this->getCity(),
|
||||
'is_utc' => $this->isUtc(),
|
||||
'uses_daylight_saving' => $this->usesDaylightSaving(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* String representation
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate timezone
|
||||
*/
|
||||
private function validate(): void
|
||||
{
|
||||
try {
|
||||
new DateTimeZone($this->value);
|
||||
} catch (\Exception $e) {
|
||||
throw new InvalidArgumentException("Invalid timezone: {$this->value}");
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user