[The following excerpt is from Chapter 5 of PHP 5 Recipes by Lee Babin, Nathan A. Good, Frank M. Kromann, Jon Stephens.]

So far, all the date and time output has been in English. From the point of view of someone for whom English is the primary language, this is not necessarily a bad thing. However, quite a lot of people in the world use other languages and prefer to use websites in those languages. You do not want to display something like “Guten Morgen! Heute is Monday, der 15th March� to users of a German-language news portal any more than English-speaking users would want to see something like “Good Morning! It’s Montag, the 15. of März� on an English-language site.
You might consider writing your own functions to deal with this type of situation, but this is not very appealing, not only because it is extra work for a German-language site but because the same task would then have to be repeated for each language. Fortunately, a much better way to accomplish this task exists. You can use the setlocale() function to change PHP’s language and related settings in a number of ways. Here you are concerned primarily with how dates and times are represented, but if internationalization is of any concern to you in your work with PHP, you should investigate this function more thoroughly.
setlocale() takes two arguments: a category (a predefined constant) and a language code (a string). To localize time and date settings, you can use either LC_ALL or LC_TIME for the category.
You can determine whether the locale was set successfully by testing the return value of setlocale(), which is either the language string on success or FALSE on failure. The languages or locales actually supported will vary from system to system; if you cannot find a value for a desired language or locale, check with your system administrator or consult the operating system documentation. On Unix systems, you can often find out what is supported by examining the contents of the /usr/share/locale directory. On Windows, use Regional Settings in the Control Panel.
If you do not know ahead of time what is supported, you can pass multiple language/locale strings to setlocale(), and PHP will test each one in succession until (you hope) one is used successfully. For example:
Once you have set the locale, you are ready to output dates and times in the target language without resorting to brute-force translation (and possible transliteration). However, you cannot use date() for this. Instead, you must use a separate function, strftime(). This function is similar to date() in that it takes a format string and an optional timestamp as arguments. Unfortunately, the similarity ends there, because the formatting characters are quite unlike those used by date(). The table below lists the characters you are most likely to need, arranged by the part of the date or time they represent. Note that not all of these are available on all platforms, and Windows has some of its own. See http://msdn.microsoft.com/ library/en-us/vclib/html/_crt_strftime.2c_.wcsftime.asp for a complete listing.
| Character | Description |
|---|---|
| Day | |
| %A | Full weekday name. |
| %a | Abbreviated weekday name. |
| %u | Weekday number (1 = Monday, 7 = Saturday). |
| %d | Day of the month, with leading zero. |
| %e | Day of the month, with leading space. |
| %j | Day of the year (001–366). Note that numbering begins with 1 and not 0. |
| Week | |
| %U | Number of the week of the year, with Sunday as the first day of the week. |
| %V | ISO-8601 number of the week of the year, with Monday as the first day of the week (01–53). |
| %W | Number of the week of the year, with Monday as the first day of the week (decimal number). |
| Month | |
| %B | Full name of the month. |
| %b or %h | Abbreviated name of the month. |
| %m | Number of the month, with leading zero. |
| Year | |
| %g | Two-digit year for ISO-8601 week of the year. |
| %G | Four-digit year for ISO-8601 week of the year. |
| %y | Two-digit year. |
| %Y | Four-digit year. |
| Hour | |
| %H | Hour (00–23). |
| %I | Hour (01–12) |
| Minute | |
| %M | Minute. |
| Second | |
| %S | Second. |
| Full Date and/or Time | |
| %c | Preferred date and time representation for the current locale. |
| %D | Current date; equivalent to %m/%d/%y. |
| %p | a.m./p.m. indicator. |
| %R | Time in 24-hour notation. |
| %r | Time in 12-hour (am/pm) notation. |
| %T | Current time; equivalent to %H:%M:%S. |
| %x | Preferred date representation. |
| %X | Preferred time representation. |
| %z or %Z | Time zone. |
| Formatting Characters | |
| %n | New line. |
| %t | Tab. |
| %% | he percent character. |
Now you are ready to put this together in a simple working example. Actually, since browsers have problems displaying more than one character set in a single page, we will use three examples.
if($loc_ru = setlocale(LC_ALL, 'ru_RU.utf8', 'rus_RUS.1251', 'rus', 'russian'))
{
echo "<p>Preferred locale for Russian on this system is \"$loc_ru\".<br />\n";
echo 'Доброе '
. 'Утро! '
. 'Сегодня '
. strftime('%A %d %B %Y', mktime()) . ".</p>\n";
}
else
echo "<p>Couldn't set a Russian locale.</p>\n";
?>
if($loc_zh = setlocale(LC_ALL, 'zh_ZH.big5', 'zh_ZH', 'chn', 'chinese'))
{
echo "<p>Preferred locale for Chinese on this system is \"$loc_zh\".<br />\n";
echo '???! ???... ' . strftime('%A %d %B %Y', mktime()) . ".</p>\n";
}
else
{
echo "<p>Sorry! No Chinese locale available on this system.</p>\n";
$lc_en = setlocale(LC_TIME, 'en_US', 'english');
echo "<p>Reverting locale to $lc_en.</p>\n";
}
?>
How It Works
Below is the output in a web browser from each of these scripts when run on a Windows system that supports German and Russian locales but no Chinese locale.
Note: LC_TIME changes only the way in which dates and times are reported but does not change other locale-dependent items such as character sets. If you use an English-language locale and need to display dates in a language (German or Spanish, for example) that uses the Latin-1 character set or a close relative such as ISO-8559-1, ISO-8859-15, or Windows-1252, you may be able to use LC_TIME. However, in the case of a language that uses non-Latin characters (such as Russian, Chinese, and some Eastern European languages with special characters not represented in Western European character sets), you will most likely have to use LC_ALL. Be aware that using setlocale() with LC_ALL will change all locale settings, not just those related to dates and times. If you will be working with currency, numbers, or sorting of strings, be sure to check the PHP manual for setlocale() and understand what all the implications might be before doing so.
The format of the language string differs between Unix and Windows systems. On Unix systems, this varies somewhat but generally takes the form lc_CC.charset, where lc represents the two-letter language code, CC represents the two-letter country code, and charset is the designation of the character set to be used. (The charset designation—including the period—is often optional.) For example, pt_BR.ISO-18859-1 might be used to represent Brazilian Portuguese. On Windows, you can use either Microsoft's three-letter language codes or the names of the languages, for example, deu or german for German-language dates and times.
The preceding excerpt is from Chapter 5 of PHP 5 Recipes by Lee Babin, Nathan A. Good, Frank M. Kromann, Jon Stephens.
First, this book is a source of instant solutions, including countless pieces of useful code that you can just copy and paste into your own applications, giving you answers fast and saving you hours of coding time. Second, this book is a useful reference to the most important aspects of the PHP 5 language, including the vital functions you know and love from previous versions of PHP, as well as the functions introduced in PHP 5. Finally, this book explains the new PHP 5 functionality in detail, including the vastly improved object-oriented capabilities and the new MySQLi database extension.

