| 1 |
<?php |
| 2 |
|
| 3 |
namespace FluentCart\App\Services\DateTime; |
| 4 |
|
| 5 |
trait CanExtractTimeZone{ |
| 6 |
public static function extractTimezone($datetime = null): \DateTimeZone |
| 7 |
{ |
| 8 |
$timezone = null; |
| 9 |
|
| 10 |
if (is_null($datetime)) { |
| 11 |
$datetime = static::now(); |
| 12 |
$timezone = $datetime->getTimezone(); |
| 13 |
} |
| 14 |
elseif ($datetime instanceof \DateTimeInterface) { |
| 15 |
$timezone = $datetime->getTimezone(); |
| 16 |
} |
| 17 |
elseif (is_numeric($datetime)) { |
| 18 |
$dt = new static('@' . (int)$datetime); |
| 19 |
$wpTimezone = wp_timezone(); |
| 20 |
$dt->setTimezone($wpTimezone); |
| 21 |
$timezone = $dt->getTimezone(); |
| 22 |
} |
| 23 |
elseif (is_string($datetime)) { |
| 24 |
$dt = static::parse($datetime); |
| 25 |
$timezone = $dt->getTimezone(); |
| 26 |
} |
| 27 |
else { |
| 28 |
throw new \InvalidArgumentException('Invalid datetime format.'); |
| 29 |
} |
| 30 |
return $timezone; |
| 31 |
} |
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
/** |
| 37 |
* Enhanced offset to named timezone mapping |
| 38 |
*/ |
| 39 |
private static function getNamedTimezoneFromOffset(string $offset): ?string |
| 40 |
{ |
| 41 |
$offsetMap = [ |
| 42 |
'+00:00' => 'UTC', |
| 43 |
'+01:00' => 'Europe/Paris', // Better than London (no DST issues) |
| 44 |
'+02:00' => 'Europe/Berlin', |
| 45 |
'+03:00' => 'Europe/Moscow', |
| 46 |
'+03:30' => 'Asia/Tehran', |
| 47 |
'+04:00' => 'Asia/Dubai', |
| 48 |
'+04:30' => 'Asia/Kabul', |
| 49 |
'+05:00' => 'Asia/Karachi', |
| 50 |
'+05:30' => 'Asia/Kolkata', |
| 51 |
'+06:00' => 'Asia/Dhaka', // Perfect for Bangladesh! |
| 52 |
'+07:00' => 'Asia/Bangkok', |
| 53 |
'+08:00' => 'Asia/Singapore', |
| 54 |
'+09:00' => 'Asia/Tokyo', |
| 55 |
'+10:00' => 'Australia/Sydney', |
| 56 |
'+11:00' => 'Australia/Melbourne', |
| 57 |
'+12:00' => 'Pacific/Auckland', |
| 58 |
'-05:00' => 'America/New_York', |
| 59 |
'-06:00' => 'America/Chicago', |
| 60 |
'-07:00' => 'America/Denver', |
| 61 |
'-08:00' => 'America/Los_Angeles', |
| 62 |
'-09:00' => 'America/Anchorage', |
| 63 |
'-10:00' => 'Pacific/Honolulu', |
| 64 |
]; |
| 65 |
|
| 66 |
return $offsetMap[$offset] ?? null; |
| 67 |
} |
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
public static function getTimezoneOffsetMinutes($timezoneName): int |
| 72 |
{ |
| 73 |
try { |
| 74 |
if (preg_match('/^([+-])(\d{2}):(\d{2})$/', $timezoneName, $matches)) { |
| 75 |
// Handle offset format like +06:00 |
| 76 |
$sign = $matches[1]; |
| 77 |
$hours = (int)$matches[2]; |
| 78 |
$minutes = (int)$matches[3]; |
| 79 |
$totalMinutes = ($hours * 60) + $minutes; |
| 80 |
return $sign === '-' ? -$totalMinutes : $totalMinutes; |
| 81 |
} else { |
| 82 |
// Handle named timezone like 'Asia/Dhaka' |
| 83 |
$timezone = new \DateTimeZone($timezoneName); |
| 84 |
$utc = new \DateTime('now', new \DateTimeZone('UTC')); |
| 85 |
$local = new \DateTime('now', $timezone); |
| 86 |
return $local->getOffset() / 60; // Convert seconds to minutes |
| 87 |
} |
| 88 |
} catch (\Exception $e) { |
| 89 |
// Fallback to WordPress GMT offset |
| 90 |
$gmt_offset = get_option('gmt_offset', 0); |
| 91 |
return $gmt_offset * 60; |
| 92 |
} |
| 93 |
} |
| 94 |
} |