98 lines
2.7 KiB
PHP
98 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\System;
|
|
|
|
use Carbon\CarbonImmutable;
|
|
use DateTimeInterface;
|
|
|
|
class TimeService
|
|
{
|
|
public function userTimezone(): string
|
|
{
|
|
$schoolConfig = config('School');
|
|
if (is_object($schoolConfig) && isset($schoolConfig->attendance['timezone'])) {
|
|
return (string) $schoolConfig->attendance['timezone'];
|
|
}
|
|
if (is_array($schoolConfig) && isset($schoolConfig['attendance']['timezone'])) {
|
|
return (string) $schoolConfig['attendance']['timezone'];
|
|
}
|
|
|
|
return (string) (config('app.timezone') ?: 'UTC');
|
|
}
|
|
|
|
public function primeFromRequest($request): void
|
|
{
|
|
$headerTz = (string) ($request?->header('X-Timezone') ?? '');
|
|
if ($headerTz === '') {
|
|
$headerTz = (string) ($request?->header('Time-Zone') ?? '');
|
|
}
|
|
|
|
if ($headerTz !== '' && in_array($headerTz, \DateTimeZone::listIdentifiers(), true)) {
|
|
// No session-backed storage; header is read per request if needed.
|
|
}
|
|
}
|
|
|
|
public function serverTimezone(): string
|
|
{
|
|
return (string) (config('app.timezone') ?: 'UTC');
|
|
}
|
|
|
|
public function nowUtc(): CarbonImmutable
|
|
{
|
|
return CarbonImmutable::now('UTC');
|
|
}
|
|
|
|
public function nowLocal(?string $tz = null): CarbonImmutable
|
|
{
|
|
return CarbonImmutable::now($tz ?: $this->userTimezone());
|
|
}
|
|
|
|
public function toUtc($value, ?string $fromTz = null, string $format = 'Y-m-d H:i:s'): ?string
|
|
{
|
|
$dt = $this->parse($value, $fromTz);
|
|
if (!$dt) {
|
|
return null;
|
|
}
|
|
|
|
return $dt->setTimezone('UTC')->format($format);
|
|
}
|
|
|
|
public function toLocal($value, ?string $sourceTz = null, ?string $targetTz = null, string $format = 'Y-m-d H:i:s'): ?string
|
|
{
|
|
$dt = $this->parse($value, $sourceTz);
|
|
if (!$dt) {
|
|
return null;
|
|
}
|
|
|
|
return $dt->setTimezone($targetTz ?: $this->userTimezone())->format($format);
|
|
}
|
|
|
|
public function formatLocal($value, string $format = 'Y-m-d', ?string $sourceTz = null): string
|
|
{
|
|
$dt = $this->parse($value, $sourceTz);
|
|
if (!$dt) {
|
|
return '';
|
|
}
|
|
|
|
return $dt->setTimezone($this->userTimezone())->format($format);
|
|
}
|
|
|
|
private function parse($value, ?string $tz = null): ?CarbonImmutable
|
|
{
|
|
if ($value instanceof DateTimeInterface) {
|
|
return CarbonImmutable::instance($value);
|
|
}
|
|
|
|
$raw = trim((string) $value);
|
|
if ($raw === '') {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return CarbonImmutable::parse($raw, $tz ?: $this->serverTimezone());
|
|
} catch (\Throwable $e) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|