Dates7 min readExamples run on PHP 8.5.10

timezone_version_get()

Learn how PHP 8.4 timezone_version_get() reports the timezone database version, what the string looks like, and how to handle it safely.

Signature

timezone_version_get(): string
Available since PHP 5.3.07.48.08.18.28.38.48.5All versions →

Purpose

PHP does not calculate time zone rules on its own. It relies on a timezone database (often called timezonedb or the Olson/IANA database) that records offsets and daylight saving changes for each region. Governments change those rules regularly, so the database is revised many times a year. timezone_version_get() tells you which revision your PHP runtime is currently using.

This is useful when you are diagnosing a bug report such as "this city shows the wrong local time", when you log environment details for support, or when a health check should warn that the time zone data is stale.

Signature

Parameters and defaults

The function takes no parameters, so there are no defaults to remember. Calling it with arguments is a mistake; PHP 8 internal functions reject unexpected arguments with an ArgumentCountError.

Return value and failure cases

The function always returns a string. According to the manual, the normal format is YYYY.increment, for example 2022.2. The first part is the year of the database release and the second part is a counter for releases within that year.

There is one documented special case. Some Linux distributions patch PHP so that it uses the operating system's time zone data instead of the copy bundled with PHP. In that situation the function returns 0.system. Your code should therefore never assume that the first part is a four digit year.

The function has no documented failure return such as false, so you do not need to compare the result against false.

Example 1: checking the type and shape of the live value

The actual version depends on the PHP build, so a portable example should check the shape instead of printing the value.

Example
<?php
$version = timezone_version_get();
echo json_encode([
    'type' => gettype($version),
    'looksValid' => preg_match('/^(?:\d{4}\.\d+|0\.system)$/', $version) === 1,
]);
Output
{"type":"string","looksValid":true}

The regular expression accepts both the usual YYYY.increment format and the 0.system marker described above.

Example 2: parsing a version string

A small helper can turn the string into structured data. Here it is fed fixed sample strings, so the result is predictable on any machine. In real code you would pass it timezone_version_get().

Example
<?php
function describe_tz_version(string $version): array
{
    if ($version === '0.system') {
        return ['source' => 'system', 'year' => null, 'increment' => null];
    }

    if (preg_match('/^(\d{4})\.(\d+)$/', $version, $m) === 1) {
        return ['source' => 'bundled', 'year' => (int) $m[1], 'increment' => (int) $m[2]];
    }

    return ['source' => 'unknown', 'year' => null, 'increment' => null];
}

echo json_encode([
    describe_tz_version('2022.2'),
    describe_tz_version('0.system'),
    describe_tz_version('abc'),
]);
Output
[{"source":"bundled","year":2022,"increment":2},{"source":"system","year":null,"increment":null},{"source":"unknown","year":null,"increment":null}]

Example 3: comparing versions correctly

To decide whether one database is newer than another, use version_compare(). Plain string comparison is unreliable because 2022.10 is newer than 2022.2, yet it sorts earlier as text.

Example
<?php
echo json_encode([
    version_compare('2022.2', '2021.5', '>'),
    version_compare('2022.10', '2022.2'),
    version_compare('2022.2', '2022.2'),
]);
Output
[true,1,0]

Edge cases

  • System data: 0.system means the data comes from the operating system. Any "is it recent enough" check based on the year will treat it as very old unless you handle it explicitly.
  • Increment is not a month: The number after the dot is a release counter, not a calendar value, and it can have more than one digit.
  • Environment differences: Two servers running the same PHP version can report different values if one uses an updated timezonedb package or a distribution patch.
  • Updating: The manual says an out-of-date version can be fixed by upgrading PHP or installing the timezonedb PECL package.

Common mistakes

  1. Hard-coding the expected value. Tests that assert an exact version break as soon as the runtime is updated. Assert the format instead.
  2. Comparing with < or > on strings. Use version_compare() so that 2022.10 is handled as a number.
  3. Confusing it with the default time zone. This function reports the data version, not the active zone. For the active zone use date_default_timezone_get().
  4. Assuming the year is always present. Guard against 0.system before extracting a year.
  5. Expecting a list of zones. The function returns one string only.
  • timezone_identifiers_list() lists the identifiers known to the current database.
  • timezone_abbreviations_list() returns abbreviation data.
  • date_default_timezone_get() returns the default zone used by date functions.
  • timezone_open() creates a DateTimeZone object.
  • version_compare() compares version-like strings safely.

Recap

timezone_version_get() takes no arguments and returns a string describing the timezonedb in use, normally YYYY.increment such as 2022.2, or 0.system on distributions that use system data. Validate the format instead of hard-coding a value, compare with version_compare(), and remember that it describes the rules database, not the current time zone.

Tested examples

Check the type and shape of the live version string
<?php
$version = timezone_version_get();
echo json_encode([
    'type' => gettype($version),
    'looksValid' => preg_match('/^(?:\d{4}\.\d+|0\.system)$/', $version) === 1,
]);
Output
{"type":"string","looksValid":true}
Parse fixed sample version strings
<?php
function describe_tz_version(string $version): array
{
    if ($version === '0.system') {
        return ['source' => 'system', 'year' => null, 'increment' => null];
    }

    if (preg_match('/^(\d{4})\.(\d+)$/', $version, $m) === 1) {
        return ['source' => 'bundled', 'year' => (int) $m[1], 'increment' => (int) $m[2]];
    }

    return ['source' => 'unknown', 'year' => null, 'increment' => null];
}

echo json_encode([
    describe_tz_version('2022.2'),
    describe_tz_version('0.system'),
    describe_tz_version('abc'),
]);
Output
[{"source":"bundled","year":2022,"increment":2},{"source":"system","year":null,"increment":null},{"source":"unknown","year":null,"increment":null}]
Compare version strings with version_compare()
<?php
echo json_encode([
    version_compare('2022.2', '2021.5', '>'),
    version_compare('2022.10', '2022.2'),
    version_compare('2022.2', '2022.2'),
]);
Output
[true,1,0]