timezone_identifiers_list
Returns an array of all IANA time zone identifiers PHP knows about, optionally filtered.
timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array- Added in PHP 5.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$timezoneGroupoptional | int= DateTimeZone::ALL | One of the DateTimeZone constants, or a bitmask of them: AFRICA, AMERICA, ANTARCTICA, ARCTIC, ASIA, ATLANTIC, AUSTRALIA, EUROPE, INDIAN, PACIFIC, UTC, ALL, ALL_WITH_BC, PER_COUNTRY. |
$countryCodeoptional | ?string= null | A two-letter uppercase ISO 3166-1 country code. Only used when timezoneGroup is DateTimeZone::PER_COUNTRY. |
Return value
arrayA numerically indexed array of time zone identifier strings such as "Europe/Berlin".
Errors
Throws a ValueError if DateTimeZone::PER_COUNTRY is used without a two-letter country code. An unrecognised value for timezoneGroup is not validated - it is treated as a bitmask and simply produces an empty or partially filtered array rather than throwing.
Changelog
- PHP 8.0.0Prior to this version, false was returned on failure.
- PHP 7.1.0countryCode is nullable now.
timezone_identifiers_list() is an alias of DateTimeZone::listIdentifiers(). It returns every identifier in the IANA database bundled with your PHP build, in the canonical Region/City form.
When to reach for it
The obvious use is building a time zone picker for a user profile. Pass a region constant to keep the list manageable, or use DateTimeZone::PER_COUNTRY with a country code once you already know the country — that turns hundreds of options into two or three.
It is also a cheap validator. Before storing a zone name that came from a request, check it is in the list (or attempt new DateTimeZone($name) in a try/catch); an unrecognised name passed to date_default_timezone_set() silently fails and leaves you in UTC.
What trips people up
By default the list excludes backward-compatibility aliases. Old values such as US/Eastern, Asia/Calcutta or the EST pseudo-zone still work when passed to DateTimeZone, but they are not returned unless you pass DateTimeZone::ALL_WITH_BC. If you validate legacy user records against the default list, historical rows will be rejected as invalid.
The contents also depend on the tzdata your build ships or the timezonedb PECL extension provides, so the count differs between servers and grows over time as new zones are added.
Example
When to use it
- Populate a time zone select box on an account settings page
- Validate a user-supplied zone name before calling date_default_timezone_set
- Narrow a signup form's zone options to the country the user already selected
Frequently asked questions
How do I get a list of time zones for one country?
Call timezone_identifiers_list(DateTimeZone::PER_COUNTRY, 'GB') with the two-letter uppercase ISO 3166-1 code. The country code is ignored for any other group constant.
Why is US/Eastern missing from the list?
It is a backward-compatibility alias, and those are excluded by default. Pass DateTimeZone::ALL_WITH_BC to include them.
Why do two servers return a different number of zones?
The list comes from the IANA tzdata compiled into PHP or supplied by the timezonedb PECL extension, and that database is updated several times a year.
More examples
Validating a submitted zone name
Both real names pass, including the legacy US/Eastern that the default list would have rejected, while the invented name is caught before it reaches DateTimeZone.
<?php
$valid = timezone_identifiers_list(DateTimeZone::ALL_WITH_BC);
foreach (['Europe/Lisbon', 'US/Eastern', 'Mars/Olympus'] as $input) {
if (in_array($input, $valid, true)) {
$tz = new DateTimeZone($input);
echo "$input => ok, offset now ", (new DateTime('now', $tz))->format('P'), "\n";
} else {
echo "$input => rejected\n";
}
}Grouping zones by region for a select box
Splitting each identifier on the first slash gives the optgroup labels. The output lists regions such as Africa, America, Asia and Europe with the number of zones in each, and single-segment entries like UTC group under their own name.
<?php
$groups = [];
foreach (timezone_identifiers_list() as $zone) {
$region = explode('/', $zone)[0];
$groups[$region][] = $zone;
}
ksort($groups);
foreach ($groups as $region => $zones) {
echo str_pad($region, 12), count($zones), "\n";
}
Discussion