Home > Software engineering >  How to get human friendly format time zone offset (PHP)
How to get human friendly format time zone offset (PHP)

Time:01-12

Help me to decide this task, please. (PHP, Symfony)

What I have: List of time zone like

"Europe/Riga"
"Europe/Rome"
"Europe/Samara"
"Europe/San_Marino"
"Europe/Sarajevo"

In result I want to see:

 ( 00:00) Riga
 ( 01:30) Rome
 ( 03:00) Samara
 (-01:00) San_Marino
 ( 05:00) Sarajevo

What I did:

$timeZoneIdentifierList = DateTimeZone::listIdentifiers();

        $timeZoneUtc = new DateTimeZone('UTC');
        $nowByUtc = new DateTime('now', $timeZoneUtc);

        foreach ($timeZoneIdentifierList as $timeZoneIdentifier) {
            $dateTimezoneItem = new DateTimeZone($timeZoneIdentifier);

            $timeZone = $dateTimezoneItem->getOffset($nowByUtc);
            
            $humanFriendlyOffset = $timeZone / 3600;
        }

And if I dump $humanFriendlyOffset I get only digital value like this: 0, 1, -7, 2, 1.5

Question: Is something prepared method in PHP/Symfony to convert

  • 1 -> 01:00,
  • -7 -> -07:00,
  • 2 -> 02:00,
  • 1.5 -> 01:30

May be exist more easy way?

CodePudding user response:

This solution creates a new DateTime object for each time zone.

$tzArr = ["Europe/Riga",
"Europe/Rome",
"Europe/Samara",
"Europe/San_Marino",
"Europe/Sarajevo",
"UTC"];

foreach($tzArr as $tz){
  $dt = date_create('Now',new DateTimeZone($tz));
  
  $formatTz = $dt->format('\(P\) e');
  echo $formatTz."<br>\n"; 
}

Output:

( 02:00) Europe/Riga
( 01:00) Europe/Rome
( 04:00) Europe/Samara
( 01:00) Europe/San_Marino
( 01:00) Europe/Sarajevo
( 00:00) UTC

With a preg_replace the continent can be hidden and an output can be achieved exactly as desired.

foreach($tzArr as $tz){
  $dt = date_create('Now',new DateTimeZone($tz));

  $loc = preg_replace('~^[a-z] /~i','', $dt->format('e'));
  $formatTz = $dt->format('\(P\) ').$loc;
  echo $formatTz."<br>\n"; 
}

Output:

( 02:00) Riga
( 01:00) Rome
( 04:00) Samara
( 01:00) San_Marino
( 01:00) Sarajevo
( 00:00) UTC

CodePudding user response:

You can use the P formatter from DateTimeInterface::format to get a friendly timezone offset, but that's on a DateTime object, not a DateTimeZone object. So you could create a DateTime object, then explicitly set its timezone to the one you want, then get its offset. Something like this

$dt = new DateTime();
foreach (DateTimeZone::listIdentifiers() as $tz) {
    $dt->setTimeZone(new DateTimeZone($tz));
    printf("(%s) %s\n", $dt->format('P'), $tz);
}

Output:

( 00:00) Africa/Abidjan
( 00:00) Africa/Accra
( 03:00) Africa/Addis_Ababa
( 01:00) Africa/Algiers
( 03:00) Africa/Asmara
( 00:00) Africa/Bamako
( 01:00) Africa/Bangui
( 00:00) Africa/Banjul
( 00:00) Africa/Bissau
  • Related