I would use the following code.
$map = array();
foreach (timezone_identifiers_list() as $zone) {
if ($timezone = timezone_open($zone)) {
if ($datetime = date_create("now", $timezone)) {
if (($offset = $timezone->getOffset($datetime)) !== FALSE && !isset($map[$offset])) {
$map[$offset][] = $zone;
}
}
}
}
Keep in mind that the same offset is used for different timezone identifies. Showing just an identifier for each offset would be less useful for users.
For example, for Europe you would show the following list. (The list is partial.)
- Europe/Amsterdam 7200
- Europe/Athens 10800
- Europe/Dublin 3600
In your list, Europe/Rome, Europe/Madrid, Europe/Malta, and Europe/Kiev would not appear because the offset is already used for the three entries I shown.
A better code would the following one.
function mymodule_get_timezones() {
$map = &drupal_static(__FUNCTION__);
if (isset($map)) {
return $map;
}
foreach (timezone_identifiers_list() as $zone) {
if ($timezone = timezone_open($zone)) {
if ($datetime = date_create("now", $timezone)) {
if (($offset = $timezone->getOffset($datetime)) !== FALSE && !isset($map[$offset])) {
$map[$offset][] = $zone;
}
}
}
}
return $map;
}
As side note, I would not use format_date()
if you use "custom" as date format, and you are not interesting in translating the returned date. In such case, the following code that is executed from format_date() is extra, and useless, for you.
// Encode markers that should be translated. 'A' becomes '\xEF\AA\xFF'.
// xEF and xFF are invalid UTF-8 sequences, and we assume they are not in the
// input string.
// Paired backslashes are isolated to prevent errors in read-ahead evaluation.
// The read-ahead expression ensures that A matches, but not \A.
$format = preg_replace(array('/\\\\\\\\/', '/(?<!\\\\)([AaeDlMTF])/'), array("\xEF\\\\\\\\\xFF", "\xEF\\\\\$1\$1\xFF"), $format);
// Call date_format().
$format = date_format($date_time, $format);
// Pass the langcode to _format_date_callback().
_format_date_callback(NULL, $langcode);
// Translate the marked sequences.
return preg_replace_callback('/\xEF([AaeDlMTF]?)(.*?)\xFF/', '_format_date_callback', $format);
In the case I described, that code can be replaced with the following one.
return date_format($date_time, $format);