skip to content

PHP: International Date Formatter

If you've just landed here it's probably because you found out that the PHP strftime function has been deprecated in PHP 8.1 meaning you have to instead use the IntlDateFormatter class for locale-specific output - which looks complicated.

Installing the module

For apache there is a package php-intl which can be installed from the command-line as follows:

# apt -u install php-intl

This will actually install a version of the package relevant to your PHP installaction. For example php7.4-intl if you are running PHP 7.4.

After installation you will need to reload the Apache configuration to make the module and its functions available in PHP:

# apachectl graceful

Now you are ready to start using the IntlDateFormatter class.

Formatting dates with strftime

Until now we've been using something like the following to format date strings:

<?PHP $timestamp = strtotime('11 November 2023 11:12:00'); echo strftime('%c', $timestamp),"<br>\n"; echo strftime('%e %B %Y', $timestamp),"<br>\n"; echo strftime('%H:%M:%S', $timestamp),"<br>\n"; echo strftime('%A', $timestamp),"<br>\n"; ?>

These and other formatting codes can be found on the PHP manual page for strftime.

which will output the following:

Sat Nov 11 11:12:00 2023 11 November 2023 11:12:00 Saturday

And by adding a simple command to change the locale:

<?PHP setlocale(LC_TIME, 'nl_NL'); ?>

we can change the output to be language-specific:

za 11 nov 2023 11:12:00 AEDT 11 november 2023 11:12:00 zaterdag

Switching to IntlDateFormatter

The major change is that rather than a single line we now have to first define a 'formatter' before we can apply it to our timestamp:

<?PHP $datefmt = datefmt_create( 'en_GB', \IntlDateFormatter::$dateType, \IntlDateFormatter::$timeType, 'Europe/London', \IntlDateFormatter::GREGORIAN ); echo datefmt_format($datefmt, time()); ?>

In the folllowing table $timeType has been set to \IntlDateFormatter::FULL while we experiment with different values for $dateType:

dateType output
FULLFriday, 2 December 2022 at 17:22:46 Greenwich Mean Time
LONG2 December 2022 at 17:22:46 Greenwich Mean Time
MEDIUM2 Dec 2022, 17:22:46 Greenwich Mean Time
SHORT02/12/2022, 17:22:46 Greenwich Mean Time
NONE17:22:46 Greenwich Mean Time

And here $dateType has been set to \IntlDateFormatter::FULL while we experiment with different values for $timeType:

timeType output
FULLFriday, 2 December 2022 at 17:22:46 Greenwich Mean Time
LONGFriday, 2 December 2022 at 17:22:46 GMT
MEDIUMFriday, 2 December 2022 at 17:22:46
SHORTFriday, 2 December 2022 at 17:22
NONEFriday, 2 December 2022

More exotic IntlDateFormatter values are available where relative values of 'yesterday', 'today' and 'tomorrow' are returned where appropriate. There is also the option of using non-Gregorian ('TRADITIONAL') calendars.

You can see from the above how to get a formatted time string in a given location ('Europe/London') and language ('en_GB') for a supplied timestamp in a range of short and long formats.

But this isn't quite what we were after as we want to be able to define our own date formats such as 'yyyy-mm-dd' or 'mm/dd/yyyy'. That is also possible, it just requires an extra 'pattern' parameter.

Custom date strings

The date formatting symbols for IntlDateFormatter are different from those you might have used for the PHP date or strftime commands.

Instructions and some examples can be found in the ICU User Guide which applies to several programming languages.

Here you can find some examples that may be useful:

pattern output
yyyyMMdd hh:mm:ss z20221202 05:22:46 GMT
MMMM YYYYDecember 2022
MM/dd/yyyy12/02/2022
yyyy-MM-dd2022-12-02
EEEE BBBBFriday in the afternoon
MMMM d 'at' h:mm aDecember 2 at 5:22 pm
yyyy.MM.dd G 'at' HH:mm:ss zzz2022.12.02 AD at 17:22:46 GMT

In each case we are preparing the date formatter using:

<?PHP $datefmt = datefmt_create( 'en_GB', \IntlDateFormatter::NONE, \IntlDateFormatter::NONE, 'Europe/London', \IntlDateFormatter::GREGORIAN, $pattern ); echo datefmt_format($datefmt, time()); ?>

While you're working with IntlDateFormatter you should be aware that it's possible both to re-use and to re-define your formatter with methods such as datefmt_set_timezone and datefmt_set_pattern on an existing format.

If you've found this article useful, or think there's someone we've missed, let us know using the feedback form below.

< PHP

Post your comment or question
top