title: PHP Timezone List
body: <p>I am looking for a way to generate a list of timezones for display in a <code>&lt;select&gt;</code> <a href="https://stackoverflow.com/questions/1727077/generating-a-drop-down-list-of-timezones-with-php/2839396#2839396">Generating a drop down list of timezones with PHP</a> </p>
  
  <pre><code>    $list = DateTimeZone::listAbbreviations();
      $idents = DateTimeZone::listIdentifiers();
  
      $data = $offset = $added = array();
      foreach ($list as $abbr =&gt; $info) {
          foreach ($info as $zone) {
              if ( ! empty($zone['timezone_id'])
                  AND
                  ! in_array($zone['timezone_id'], $added)
                  AND 
                    in_array($zone['timezone_id'], $idents)) {
                  $z = new DateTimeZone($zone['timezone_id']);
                  $c = new DateTime(null, $z);
                  $zone['time'] = $c-&gt;format('H:i a');
                  $data[] = $zone;
                  $offset[] = $z-&gt;getOffset($c);
                  $added[] = $zone['timezone_id'];
              }
          }
      }
  
      array_multisort($offset, SORT_ASC, $data);
      $options = array();
      foreach ($data as $key =&gt; $row) {
          $options[$row['timezone_id']] = $row['time'] . ' - '
                                          . formatOffset($row['offset']) 
                                          . ' ' . $row['timezone_id'];
      }
  
      // now you can use $options;
  
  function formatOffset($offset) {
          $hours = $offset / 3600;
          $remainder = $offset % 3600;
          $sign = $hours &gt; 0 ? '+' : '-';
          $hour = (int) abs($hours);
          $minutes = (int) abs($remainder / 60);
  
          if ($hour == 0 AND $minutes == 0) {
              $sign = ' ';
          }
          return 'GMT' . $sign . str_pad($hour, 2, '0', STR_PAD_LEFT) 
                  .':'. str_pad($minutes,2, '0');
  
  }
  </code></pre>
  
  <p>When I checked my country, the offset was wrong, I am in Asia/Singapore, it should be UTC/GMT +8 <a href="http://www.timeanddate.com/worldclock/city.html?n=236" rel="noreferrer">http://www.timeanddate.com/worldclock/city.html?n=236</a> but according to the generated list its +9. Is there some kind of logic error? The time was correct tho</p>
  
  <p>Is there a better way to generate this list? from the same question in the link above, </p>
  
  <pre><code>static $regions = array(
      'Africa' =&gt; DateTimeZone::AFRICA,
      'America' =&gt; DateTimeZone::AMERICA,
      'Antarctica' =&gt; DateTimeZone::ANTARCTICA,
      'Aisa' =&gt; DateTimeZone::ASIA,
      'Atlantic' =&gt; DateTimeZone::ATLANTIC,
      'Europe' =&gt; DateTimeZone::EUROPE,
      'Indian' =&gt; DateTimeZone::INDIAN,
      'Pacific' =&gt; DateTimeZone::PACIFIC
  );
  foreach ($regions as $name =&gt; $mask) {
      $tzlist[] = DateTimeZone::listIdentifiers($mask);
  }
  </code></pre>
  
  <p>This just gets the identifiers I want a friendly display name eg. UTC+8 Asia/Singapore or something similar. How can I get that?</p>