Lecture
This article discusses the changes in the list of supported time zones in PHP between PHP 5.6 and PHP 8. It explains why some zones were removed or renamed, why this was done, and how this affects development. It also provides tips on how to work with timezone functions and ensure compatibility of code across different PHP versions.
Reference context
PHP uses a list of time zones based on the tz (IANA) database and updates it regularly with releases. The timezone_identifiers_list() function returns all available identifiers, including new and obsolete ones, depending on the parameters
Although the full list of changes between PHP 5.6 and PHP 8 is not explicitly listed in the PHP documentation, it can be noted that deprecated timezone identifiers have been gradually removed or replaced in accordance with the official IANA recommendations. We will conduct research for this , for example, we found 6 deprecated identifiers between PHP 5.6.20 and PHP 8.2.0
Europe/Zaporozhye Europe/Uzhgorod
Both of these zones - Europe/Zaporozhye and Europe/Uzhgorod - already existed in older versions of PHP (including 5.6), and in new versions of PHP 8 they are considered obsolete, but have not yet been removed.
Story:
These zones appeared in the IANA database in the 1990s as separate time zones for individual regions of Ukraine (Zaporizhzhia and Uzhgorod), where there were once time differences.
Since the mid-1990s, these regions have been fully synchronized with the main Europe/Kiev (and now Europe/Kyiv) zone, so separate identifiers are no longer needed.
In recent versions of tzdata they are marked as deprecated and are aliases to Europe/Kyiv.
In PHP 8:
Europe/Zaporozhye → alias Europe/Kyiv
Europe/Uzhgorod → alias Europe/Kyiv
That is, in PHP 5.6 and PHP 8 these zones formally exist, but in PHP 8 they no longer carry unique time rules.
The old time zone corresponding to Europe/Kyiv is Europe/Kiev.
Story:
Until the end of 2022, the IANA database used the name Europe/Kiev, based on Russian transliteration.
In October 2022, in tzdata 2022b, the identifier was renamed to Europe/Kyiv to match the Ukrainian Latin transliteration.
In PHP 5.6 and up to PHP 8.1, only Europe/Kiev will be available. In PHP 8.2, Europe/Kyiv was introduced, but Europe/Kiev remains as a legacy alias for compatibility.
On new versions it is better to use Europe/Kyiv, but if your code should work in old PHP, you will have to check and replace the name if necessary.
One of the key changes was the renaming of the Europe/Kiev zone to Europe/Kyiv in the new version of the time zone database. This reflects the current official spelling of the name of the capital of Ukraine.
PHP versions up to and including 8.2 used the old Europe/Kiev identifier, and starting with PHP 8.2 — Europe/Kyiv. To avoid crashes, especially in projects where old values were stored, WordPress made changes: it added support for both variants and uses the DateTimeZone::ALL_WITH_BC constant to take obsolete identifiers into account during validation and normalization.
The old time zone equivalent to Pacific/Kanton is Pacific/Enderbury.
Story:
Before the IANA database updates in 2021, Kantona Island, Kiribati used the identifier Pacific/Enderbury.
Following clarification of geographical names and administrative divisions, a new identifier, Pacific/Kanton, was introduced and Pacific/Enderbury was deprecated (backward compatibility is maintained through aliases).
In PHP 5.6 you will only find Pacific/Enderbury.
If you set Pacific/Enderbury in old code, it will work as Pacific/Kanton alias on newer PHP versions, but it is better to update to the current name to avoid warnings in the future.
Asia/Qostanay
The old time zone closest to Asia/Qostanay is Asia/Almaty.
Story:
Until October 2018, the Kostanay region of Kazakhstan did not have a separate identifier in the IANA database and used the Asia/Almaty zone.
In October 2018, a separate zone Asia/Qostanay (UTC+6) was added to the tz database to reflect the fact that the region switched to a permanent time different from some other regions of Kazakhstan.
In PHP 5.6 this zone was not yet available, so old code could use:
date_default_timezone_set('Asia/Almaty');
as equivalent, but with the caveat that after the emergence of Asia/Qostanay their time regimes may diverge in historical data.
America/Punta Arenas
In the IANA time zone database, the old zone that was close in time to America/Punta_Arenas is America/Santiago.
Historically:
Until 2016, Chilean Patagonia (city of Punta Arenas) used the same time as Santiago, so in PHP 5.6 America/Punta_Arenas did not exist as a separate zone - America/Santiago was used.
Since the end of 2016, the Punta Arenas region has switched to permanent UTC−3, without daylight saving time, and a new identifier America/Punta_Arenas has appeared in the tz database.
That is, if you don't have this zone in your old code or in PHP 5.6, a safe alternative is America/Santiago, but with the understanding that after 2016 it no longer matches the offset.
Relevance: Time zone identifiers are updated as geopolitical and administrative changes occur.
Accuracy: Correct display of time (including daylight saving time) is critical.
Compatibility: For correct operation and backward compatibility, especially in projects with migrations, both identifier variants must be taken into account.
Timezone handling functions: When using timezone_identifiers_list() it is better to pass the DateTimeZone::ALL_WITH_BC flag to include obsolete zones.
Normalize input data: If the code or user enters old identifiers, it is worth converting them to the current ones.
Tests and validation: It is recommended to use “safe” identifiers in test scenarios and settings, such as Europe/Helsinki, which are close in location but stable
// Get all identifiers (including obsolete ones)
$allZones = DateTimeZone::ALL_WITH_BC ? DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) : DateTimeZone::listIdentifiers();
// Validate timezone taking into account obsolete values $tz = 'Europe/Kiev';
if (!in_array($tz, $allZones, true))
{
$tz = 'Europe/Kyiv'; // replace with the current version
}
date_default_timezone_set($tz);
If you are using an old version of PHP but want to save new timezones, then you need to redefine the system class
class DateTimeZoneForPhp56 extends \DateTimeZone
{
public function __construct($timezone)
{
//in php v8.2 Added:
// America/Nuuk
// America/Punta_Arenas
// Asia/Qostanay
// Europe/Kyiv
// Pacific/Kanton
//in php v8.2 Removed:
// America/Godthab
// America/Nipigon
// America/Rainy_River
// America/Thunder_Bay
// Australia/Currie
// Europe/Kiev
// Europe/Uzhgorod
// Europe/Zaporozhye
// Pacific/Enderbury
switch ($timezone) {
case 'Europe/Kyiv' :
case 'Europe/Uzhgorod' :
case 'Europe/Zaporozhye' :
$timezone = 'Europe/Kiev';
break;
case 'America/Nuuk' :
$timezone = 'America/Godthab';
break;
case 'America/Punta_Arenas' :
$timezone = 'America/Santiago';
break;
case 'Asia/Qostanay' :
$timezone = 'Asia/Almaty';
break;
case 'Pacific/Kanton' :
$timezone = 'Pacific/Enderbury';
break;
}
parent::__construct($timezone);
}
}
To determine the difference between the list of old and new time zones, we will execute the script
$textOld = << Africa/Abidjan
***
[424] => UTC
TXT;
$textNew = << Africa/Abidjan
***
[419] => UTC
TXT;
// Function for parsing a text array
function parseTextToArray($text) {
$lines = explode("\n", $text);
$values = [];
foreach ($lines as $line) {
if (preg_match('/=>\s*(.+)$/', $line, $matches)) {
$values[] = trim($matches );
}
}
return array_unique($values);
}
// Parse text into arrays
$oldArray = parseTextToArray($textOld);
$newArray = parseTextToArray($textNew);
// Comparison
$added = array_diff($newArray, $oldArray);
$removed = array_diff($oldArray, $newArray);
// Conclusion
echo "✅ Added:\n";
foreach ($added as $zone) {
echo " + $zone\n";
}
echo "\n❌ Removed:\n";
foreach ($removed as $zone) {
echo " - $zone\n";
}
✅ Added:
+ America/Nuuk
+ America/Punta_Arenas
+ Asia/Qostanay
+ Europe/Kyiv
+ Pacific/Kanton
❌ Removed:
- America/Godthab
- America/Nipigon
- America/Rainy_River
- America/Thunder_Bay
- Australia/Currie
- Europe/Kiev
- Europe/Uzhgorod
- Europe/Zaporozhye
- Pacific/Enderbury
- Pacific/Johnston
to get all time zones in php 5.6/8.1 we used the call
print_r(DateTimeZone::listIdentifiers());
and saved the result in a text file
Comments
To leave a comment
Running server side scripts using PHP as an example (LAMP)
Terms: Running server side scripts using PHP as an example (LAMP)