LC_MESSAGES for system responses (available if PHP was compiled with
libintl)

locale

If locale is NULL or the empty string
"", the locale names will be set from the
values of environment variables with the same names as the above
categories, or from "LANG".

If locale is "0",
the locale setting is not affected, only the current setting is returned.

If locale is an array or followed by additional
parameters then each array element or parameter is tried to be set as
new locale until success. This is useful if a locale is known under
different names on different systems or for providing a fallback
for a possibly not available locale.

...

(Optional string or array parameters to try as locale settings until
success.)

/* try different possible locale names for german as of PHP 4.3.0 */$loc_de = setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');echo "Preferred locale for german on this system is '$loc_de'";?>

Notes

Warning

The locale information is maintained per process, not per thread. If you
are running PHP on a multithreaded server API like IIS, HHVM or Apache on
Windows, you may experience sudden changes in locale settings while a
script is running, though the script itself never called
setlocale(). This happens due to other scripts
running in different threads of the same process at the same time,
changing the process-wide locale using setlocale().

User Contributed Notes 39 notes

be careful with the LC_ALL setting, as it may introduce some unwanted conversions. For example, I used

setlocale (LC_ALL, "Dutch");

to get my weekdays in dutch on the page. From that moment on (as I found out many hours later) my floating point values from MYSQL where interpreted as integers because the Dutch locale wants a comma (,) instead of a point (.) before the decimals. I tried printf, number_format, floatval.... all to no avail. 1.50 was always printed as 1.00 :(

When I set my locale to :

setlocale (LC_TIME, "Dutch");

my weekdays are good now and my floating point values too.

I hope I can save some people the trouble of figuring this out by themselves.

i.e.:When trying to use "pt_BR" on some servers you will ALWAYS get false. Even with other languages.

The locale string need to be supported by the server. Sometimes there are diferents charsets for a language, like "pt_BR.utf-8" and "pt_BR.iso-8859-1", but there is no support for a _standard_ "pt_BR".

This problem occours in Windows platform too. Here you need to call "portuguese" or "spanish" or "german" or...

Maybe the only way to try to get success calling the function setlocale() is:setlocale(LC_ALL, "pt_BR", "pt_BR.iso-8859-1", "pt_BR.utf-8", "portuguese", ...);

But NEVER trust on that when making functions like date conversions or number formating. The best way to make sure you are doing the right thing, is using the default "en_US" or "en_UK", by not calling the setlocale() function. Or, make sure that your server support the lang you want to use, with some tests.

Remember that: Using the default locale setings is the best way to "talk" with other applications, like dbs or rpc servers, too.

When i tried to get the current locale (e.g. after i set the lang to german with setlocale(LC_ALL, 'de_DE'); ), the following did not work on my suse linux 9.0-box:$currentLocale = setlocale(LC_ALL, NULL);This code did a reset to the server-setting.

$currentLocale = setlocale(LC_ALL, 0); works perfectly for me, but the manual says NULL and 0 are equal in this case, but NULL seems to act like "".

In *some* Windows systems, setting LC_TIME only will not work, you must either set LC_ALL or both LC_CTYPE and LC_TIME. BUT if you have already set LC_TIME using setlocale earlier in the script, dates will not be affected! For example:<?phpsetlocale(LC_TIME, 'greek');setlocale(LC_CTYPE, 'greek');?>will not work, while <?phpsetlocale(LC_CTYPE, 'greek');setlocale(LC_TIME, 'greek');?>will do the job.

I experienced the behavior stated in the above Warning box: Running PHP5 on a multithreaded Apache made the current locale change sometimes all of a sudden within a script, so strftime() output wasn't in the required format.

I recompiled Apache with the prefork MPM and now it works like a charm. Took me a long time to find out the reason as I overlooked the warning box searching for either a bug report or a programming error of mine...

The locale argument to the setlocale function takes the following form:setlocale( LC_ALL, "<language>_<country>.<code_page>" );

in short, if you want use for example: es_CO.UTF-8 it must be in Windows: Spanish_Colombia.1252

The code page 1252 is ISO-8859-1 (windows-1252 ANSI Latin 1; Western European (Windows)

Windows use different languages code from Unix, for example, es_CO becomes es-CO or Spanish_Colombia, also it doesn't support UTF-8 charset as is shown in their website: https://msdn.microsoft.com/en-us/library/x99tb11d(v=vs.140).aspx

"The set of available locale names, languages, country/region codes, and code pages includes all those supported by the Windows NLS API except code pages that require more than two bytes per character, such as UTF-7 and UTF-8. If you provide a code page value of UTF-7 or UTF-8, setlocale will fail, returning NULL."

//Recover to the default setting$skipConstants = array( //these will be returned by setlocale(LC_ALL, 0), but don't exist anymore.'LC_PAPER','LC_NAME','LC_ADDRESS','LC_TELEPHONE','LC_MEASUREMENT','LC_IDENTIFICATION');

Posting this in the hope it might be useful to others, as I could find very little info anywhere. If you want to use a Welsh locale and have the suitable language support installed, you pass 'cym' (abbreviated form of Cymraeg) to setlocale:

There is a new PECL extension under development called intl (it will be available in PHP5.3). Meanwhile all who rely on the setlocale() and friends should be aware about the limitations of them as covered in this post on the onPHP5.com blog: http://www.onphp5.com/article/22

On Linux/Apache, when you install and try to use a new locale, the setlocale() function with the new locale will fail sometimes, but not always. To furthermore complicate, setlocale() will always complete with any of the previously installed locales. This would seem a really weird behaviour, which you can fix by restarting Apache, as Kari Sderholm aka Haprog mentioned, but I felt it needed to be properly pointed out.

According to MSDN, Windows setlocale()'s implementation does not support UTF-8 encoding.

Citation from "MSDN setlocale, _wsetlocale" page (http://msdn.microsoft.com/en-us/library/x99tb11d.aspx):
The set of available languages, country/region codes, and code pages includes all those supported by the Win32 NLS API except code pages that require more than two bytes per character, such as UTF-7 and UTF-8. If you provide a code page like UTF-7 or UTF-8, setlocale will fail, returning NULL.

So basically, code like
<?php setlocale(LC_ALL, 'Czech_Czech Republic.65001'); // 65001 is UTF-8 codepage ?>
does not work on Windows at all.

Be carefull - setting a locale which uses commas instead of dots in numbers may cause a mysql db not to understand the query:
<?php
setlocale(LC_ALL,"pl");
$price = 1234 / 100; // now the price looks like 12,34
$query = mysql_query("SELECT Id FROM table WHERE price='".$price."'");
?>
Even if there is a price 12.34 - nothing will be found

On Novell Netware, the language codes require hyphens, not underscores, and using anything other than LC_ALL doesn't work directly.

So... (from their support list)....

You have to set TIME, NUMERIC etc. info in two steps as given below rather than one. This is due to the limitation of setlocale function of LibC.<?php setlocale(LC_ALL, 'es-ES');$loc = setlocale(LC_TIME, NULL); echo strftime("%A %e %B %Y", mktime(0, 0, 0, 12, 22, 1978));// jeuves 22 diciembre 1978?>This should work.

// dear php developers, how stupid is that?// I tell you: it is very very stupid! The problem exists since years and nothing happens (see bug #54391)

// this code will not remove all your photos of the last 10 years :)function binary_safe_escapeshellarg_that_is_not_totally_buggy_and_do_not_remove_f___ing_characters($string){ return(@sprintf("'%s'", @strtr($string, Array("\x27" => "\x27\x5C\x27\x27"))));};

if your server is an ubuntu (debian like)you need to install the locales you want (default is english and your language) go to aptitude and install -language-pack-*-base it will resolve dependencies and will try to install a suggested package, remove it if you don't care and proceed.

Please take heed and read the warning above if you are running on a XAMPP or any other Windows apache server! It just took me far too long to figure this out; and all the while there was a warning right on the page.

If you're experiencing shifting locale settings (check with setlocale(LC_ALL,0), returning the current locale stuff) and you're running a windows server, then it's not just you! Again, I urge everyone to read the red, but oh so easy not to read, warning message on this page.