You get a bonus - 1 coin for daily activity. Now you have 1 coin

The Evolution of Time Zones in PHP: What's Added, What's Removed, and Why — From PHP 5.6 to PHP 8

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.

The Evolution of Time Zones in PHP: Whats Added, Whats Removed, and Why — From PHP 5.6 to PHP 8

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

Renaming regions: example "Kiev → Kyiv" deletions and obsolete zones

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.

Europe/Kyiv

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.

Pacific/Canton

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.

What are the changes for and why do they happen?

  • 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.

How does this affect PHP development?

  • 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

Example of usage in code

// 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);
    }
}

Study

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";
}
  

Result

✅ 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
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Running server side scripts using PHP as an example (LAMP)

Terms: Running server side scripts using PHP as an example (LAMP)