Color-coded map of world time-zones.

PHP INTL: Fix Missing Or Incorrect Time-zone Offset

The INTL extension is great for showing translated strings as well as formatting dates and numbers in a way users in different locales expect. But sometimes IntlDateFormatter outputs something that isn’t correct or throws an error. Questions about incorrect or missing time-zone offsets are showing up more often. Let’s go over why that is and how you can fix it.

When you format a date with a given time-zone, the INTL extension calls the International Components for Unicode (ICU) library. That library contains a vast data store of formatting expectations for many different locales (a combination of a countries and/or language). It also includes a list of time-zones, their names, abbreviations, offsets and when and if they use daylight saving time (DST). Except time-zones change periodically and in some cases, quite often.

When do time-zones change?

While most Western time-zones tend to be quite stable with few changes, others do not. The Middle East, Central & South America, Asia and parts of Europe have seen a number of changes over the years. Locations create new time-zones, remove others, and change others if or when they observe DST.

There is no way to predict when these changes occur. Each country and even cities or regions determine when they are going to make a change. They (or others with knowledge of the change) then submit this information to the IANA to update their time-zone database (TZDB). Throughout the year new versions are released.

How to fix a missing or incorrect time-zone

The issue boils down to out-of-date data. Servers want to keep their software as stable as possible. Some are running software that is a decade or more old. It is possible to update the timezone information, even without administrative access.

Identify the version of the ICU library that is currently in use by using phpinfo() or the command line to view the installed version.

Screen capture of a phpinfo() function call showing the INTL extension and data version.

Running version 54 or newer will allow you to drop-in the necessary files. Otherwise it will likely be more complicated.

Next, download the latest time-zone data files:
https://github.com/unicode-org/icu-data/tree/main/tzdata/icunew/

To get the right files, browse to the newest directory. It is based on the year followed by a letter. The latest versions are followed by a /44. Within that directory, there are 3 others:

  • be (big endian)
  • ee (IBM mainframes using EBCDIC character sets)
  • le (little endian)

Choose the endianness that fits your system. The vast majority will use little endian. Within that directory will be 4 files:

  • metaZones.res
  • timezoneTypes.res
  • windowsZones.res
  • zoneinfo64.res

Download and place those files in a directory the web application has access to read. Finally, let the ICU library know to use these files for the time-zone database resource:

PHP
putenv('ICU_TIMEZONE_FILES_DIR=/path/to/tzdb/directory');

Put this script as early as possible in your application. For instance, a bootstrap file or prepend directive. Depending on your server setup, you may need to restart the application and/or web server. The timezone you were missing or time that was incorrect will be correct.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *