See also the Timezone API we have exposed at: /api/tz - it's updated regularly

We've seen loads of methods for working with Time Zones in PHP. Here's the one we use which on it's face appears to be more compatible and has fewer dependencies.

Getting a list of TimeZones

One of the first operations necessary is to get a list of time zones, for this we use the most popular one: the Olson Database

$tza = array();
$tab = file('/usr/share/zoneinfo/zone.tab');
foreach ($tab as $buf)
{
    if (substr($buf,0,1)=='#') continue;
    $rec = preg_split('/\s+/',$buf);
    $key = $rec[2];
    $val = $rec[2];
    $c = count($rec);
    for ($i=3;$i<$c;$i++) {
        $val.= ' '.$rec[$i];
    }
    $tza[$key] = $val;
    ksort($tza);
}
echo count($tza);
print_r($tza);

The above script gives an array that looks like (this is just a small sample).

[Africa/Kinshasa] => Africa/Kinshasa west Dem. Rep. of Congo
[Africa/Tripoli] => Africa/Tripoli
[America/Atikokan] => America/Atikokan Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
[America/Curacao] => America/Curacao
[Asia/Aqtau] => Asia/Aqtau Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
[Asia/Tokyo] => Asia/Tokyo
[Australia/Darwin] => Australia/Darwin Northern Territory
[Europe/Moscow] => Europe/Moscow Moscow+00 - west Russia
[Pacific/Auckland] => Pacific/Auckland most locations
[Pacific/Tahiti] => Pacific/Tahiti Society Islands

Using the Time Zones

To make these timezones useful you'll have to have PHP do some thing with them.

$time = time();
echo "Time: $time\n";
echo "Local Time: " . strftime('%F %T',$time) . "\n";

// Time in Tahiti
ini_set('date.timezone','Pacific/Tahiti');
date_default_timezone_set('Pacific/Tahiti');

$time = time();
echo "Time: $time\n";
echo "Tahiti Time: " . strftime('%F %T',$time) . "\n";

Which gives the results

Time: 1711646942
Local Time: 2024-03-28 17:29:02
Time: 1711646942
Tahiti Time: 2024-03-28 07:29:02

And to be really efficient this data would be loaded into a memcached system.

Other Methods

Heres a few other methods we've seen.

Using MySQL Backend

This involves importing the Olson zoneinfo into a MySQL database. We avoid this one because of the dependency on MySQL and database connection+query.

# Import Timezones to MySQL
root@host ~ # mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
// Get available timezones
$res = $db->query("SELECT * FROM mysql.time_zone_name ORDER BY Name");
$tza = $res->fetchAllAsObjects();

With caching it would be better, but mabye now the app cannot use Sqlite or PostgreSQL or MS-SQL

Hard Coding Stuff

This is the worst idea, hard coding something to UTC - 700 for example. This code works in some fashion like this (but some implementations we've seen were over 100 lines and still incomplete).

switch ($timezone) {
case 'EST':
    return time() - 60 * 4;
case 'PST':
    return time() - 60 * 8;
}

This is problematic because it would require coding for every time zone (Olson has over 400) and does not account for daylight savings variances.

See Also