PHP 5.5.16 is released

setlocale

(PHP 4, PHP 5)

setlocaleModifie les informations de localisation

Description

string setlocale ( int $category , string $locale [, string $... ] )
string setlocale ( int $category , array $locale )

Modifie les informations de localisation.

Liste de paramètres

category

category est une constante (ou une chaîne) qui spécifie la catégorie de fonctions affectées par la configuration de localisation :

  • LC_ALL pour toutes les constantes suivantes
  • LC_COLLATE pour la comparaison de chaînes de caractères. Voir strcoll()
  • LC_CTYPE pour la classification et la conversion de caractères. Voir strtoupper()
  • LC_MONETARY pour localeconv()
  • LC_NUMERIC pour le séparateur décimal. Voir localeconv()
  • LC_TIME pour le format de date et d'heure avec strftime()
  • LC_MESSAGES pour les réponses système (disponible si PHP a été compilé avec libintl)

locale

Si locale est NULL ou la chaîne vide (""), les noms de locales seront pris dans l'environnement, à partir des variables de même nom que les catégories ci-dessus, ou depuis "LANG".

Si locale vaut "0", la configuration locale ne sera pas modifiée, et la configuration courante sera retournée.

Si locale est un tableau ou bien est suivi par des paramètres additionnels, alors chaque élément du tableau ou chaque paramètre tente d'être défini comme nouvelle locale jusqu'à ce qu'un réussisse. Cela est pratique si la locale est connue sous différents noms sur des systèmes différents ou bien pour prévoir une autre valeur en cas de non disponibilité de la locale choisie.

...

(Chaîne ou tableau de paramètres optionnel à essayer comme configuration de la locale jusqu'à réussite.)

Note:

Sous Windows, setlocale(LC_ALL, '') définit les noms de la locale depuis la configuration de la langue/de la région du système d'exploitation (accessible depuis le Panneau de Contrôle).

Valeurs de retour

Retourne la nouvelle configuration locale, ou FALSE si la localisation n'est pas implémentée sur votre plate-forme, si la variable de localisation n'existe pas, ou si la catégorie spécifiée n'est pas valide.

Un nom de catégorie invalide générera un message d'alerte. La liste des noms de locales/catégories peut être trouvée en consultant la » RFC 1766 ainsi que l'» ISO 639. Les différentes plates-formes possèdent des conventions de nommages différentes.

Note:

La valeur retournée par setlocale() dépend du système sur lequel PHP est installé. setlocale() retourne exactement ce que la fonction système setlocale retourne.

Historique

Version Description
5.3.0 Cette fonction émet désormais une alerte E_DEPRECATED si une chaîne est passée comme paramètre category au lieu d'une des constantes LC_*.
4.3.0 Passer plusieurs locales devient possible.
4.2.0 Passer category en tant que chaîne est déconseillé, utilisez les constantes mentionnées plus haut à la place. Les passer en tant que chaînes (entre guillemets) provoquera l'affichage d'un message d'avertissement.

Exemples

Exemple #1 Exemple avec setlocale()

<?php
/* Configure le script en hollandais */
setlocale(LC_ALL'nl_NL');

/* Affiche : vrijdag 22 december 1978 */
echo strftime("%A %e %B %Y"mktime(00012221978));

/* Essai de différentes valeurs possible pour l'allemand depuis PHP 4.3.0 */
$loc_de setlocale(LC_ALL'de_DE@euro''de_DE''de''ge');
echo 
"L'identifiant de l'allemand sur ce système est '$loc_de'";
?>

Exemple #2 Exemple avec setlocale() sous Windows

<?php
/* Configure le script en hollandais */
setlocale(LC_ALL'nld_nld');

/* Affiche : vrijdag 22 december 1978 */
echo strftime("%A %d %B %Y"mktime(00012221978));

/* Essai de différentes valeurs possible pour l'allemand depuis PHP 4.3.0 */
$loc_de setlocale(LC_ALL'de_DE@euro''de_DE''deu_deu');
echo 
"L'identifiant de l'allemand sur ce système est '$loc_de'";
?>

Notes

Avertissement

L'information locale est maintenue par processus, non par thread. Si vous faites fonctionner PHP sur un serveur multi-threadé comme IIS ou Apache sur Windows, vous pourriez obtenir des changements soudains des configurations locales pendant qu'un script fonctionne, même si celui-ci n'appelle jamais la fonction setlocale(). Ceci survient à cause des autres scripts qui fonctionnent dans des threads différents du même processus. Ces scripts changent les configurations locales dans le processus au complet en utilisant la fonction setlocale().

Astuce

Les utilisateurs de Windows trouverons des informations utiles à propos du paramètre locale sur le site web MSDN de Microsoft. Les valeurs de locales supportées peuvent être trouvées » sur la page de la documentation des chaînes du langage et les chaînes de pays/région » sur la page de la documentation des chaînes de pays/région.

add a note add a note

User Contributed Notes 37 notes

up
32
r dot nospam dot velseboer at quicknet dot nospam dot nl
11 years ago
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.

Rob
up
10
russ at eatmymonkeydust dot com
2 years ago
If you are looking for a getlocale() function simply pass 0 (zero) as the second parameter to setlocale().

Beware though if you use the category LC_ALL and some of the locales differ as a string containing all the locales is returned:

<?php
echo setlocale(LC_ALL, 0);

// LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;
// LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C

echo setlocale(LC_CTYPE, 0);

// en_US.UTF-8

setlocale(LC_ALL, "en_US.UTF-8");
echo
setlocale(LC_ALL, 0);

// en_US.UTF-8

?>

If you are looking to store and reset the locales you could do something like this:

<?php

$originalLocales
= explode(";", setlocale(LC_ALL, 0));
setlocale(LC_ALL, "nb_NO.utf8");

// Do something

foreach ($originalLocales as $localeSetting) {
  if (
strpos($localeSetting, "=") !== false) {
    list (
$category, $locale) = explode("=", $localeSetting);
  }
  else {
   
$category = LC_ALL;
   
$locale   = $localeSetting;
  }
 
setlocale($category, $locale);
}

?>

The above works here (Ubuntu Linux) but as the setlocale() function is just wrapping the equivalent system calls, your mileage may vary on the result.
up
6
brice/axice/be
5 years ago
Pay attention to the syntax.
- UTF8 without dash ('-')
- locale.codeset and not locale-codeset.

Stupid newbie error but worth knowing them when starting with gettext.

<?php
$codeset
= "UTF8"// warning ! not UTF-8 with dash '-'
       
// for windows compatibility (e.g. xampp) : theses 3 lines are useless for linux systems

putenv('LANG='.$lang.'.'.$codeset);
putenv('LANGUAGE='.$lang.'.'.$codeset);
bind_textdomain_codeset('mydomain', $codeset);

// set locale
bindtextdomain('mydomain', ABSPATH.'/locale/');
setlocale(LC_ALL, $lang.'.'.$codeset);
textdomain('mydomain');
?>

where directory structure of locale is (for example) :
locale/fr_FR/LC_MESSAGES/mydomain.mo
locale/en_US/LC_MESSAGES/mydomain.mo

and ABSPATH is the absolute path to the locale dir

further note, under linux systems, it seems to be necessary to create the locale at os level using 'locale-gen'.
up
8
Kari Sderholm aka Haprog
5 years ago
It took me a while to figure out how to get a Finnish locale correctly set on Ubuntu Server with Apache2 and PHP5.

At first the output for "locale -a" was this:
C
en_US.utf8
POSIX

I had to install a finnish language pack with
"sudo apt-get install language-pack-fi-base"

Now the output for "locale -a" is:
C
en_US.utf8
fi_FI.utf8
POSIX

The last thing you need to do after installing the correct language pack is restart Apache with "sudo apache2ctl restart". The locale "fi_FI.utf8" can then be used in PHP5 after restarting Apache.

For setting Finnish timezone and locale in PHP use:
<?php
date_default_timezone_set
('Europe/Helsinki');
setlocale(LC_ALL, array('fi_FI.UTF-8','fi_FI@euro','fi_FI','finnish'));
?>
up
4
birkholz at web dot de
9 years ago
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 "".
up
5
Anonymous
8 years ago
The example from bruno dot cenou at revues dot org below shows the possibility, but I want to spell it out: you can add charset info to setlocale.

Example:

Into my utf-8-encoded page I want to insert the name of the current month, which happens to be March, in German "März" - with umlaut. If you use

   setlocale(LC_TIME, 'de_DE');
   echo strftime("%B");

this will return "M&auml;rz", but that html-entity will look like this on a utf-8 page: "M?rz". Not what I want.

But if you use

   setlocale(LC_TIME, 'de_DE.UTF8');  // note the charset info !
   echo strftime("%B");

this returns "M√§rz", which, on utf-8, looks like it should: "März".
up
3
Leigh Morresi
5 years ago
Setting locale that is not supported by your system will result in some string operations returning a question mark "?" in your strings where it needs to perform transliteration.

1) Always check the return of setlocale() to ensure it has set to something supported

2) on Linux you can use the "locale -a" command to find a list of supported locales
up
1
phcorp
3 years ago
To find the locale of a Unix system:
<?php system('locale -a') ?>
up
2
de ronino at kde (reverse it)
6 years ago
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...
up
2
garygendron at yahoo dot com
4 years ago
For a php Mysql query, you could also use, for french canadian, in this example :

$query = 'SET lc_time_names = "fr_CA"';
$result = mysql_query($query) or die("Query failed");

$query = 'SELECT @@lc_time_names';
$result = mysql_query($query) or die("Query failed");

$query = 'SELECT id, created, YEAR(created) as year, MONTH(created) as month,' .
' CONCAT_WS(" ", MONTHNAME(created), YEAR(created)) as archive' .           
' FROM #__TABLE as e' .
' GROUP BY archive' .
' ORDER BY id DESC';

Your data will be displayed in any locale setting you want. You may even $_GET[lc_time_name] from your multilanguage website.
up
1
wisborg
5 years ago
It is correct as stated below that it is common that the UTF-8 should be used without the dash. However on some systems (e.g. MacOS 10.4) the dash is essential.
up
1
Sven K
8 years ago
If your system doesn't show any installed locales by "locale -a", try installing them by "dpkg-reconfigure locales" (on debian).
up
1
dv at josheli dot com
10 years ago
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.

or of course, reset LC_ALL...
<?php
setlocale
(LC_ALL, 'es-ES');
echo
strftime("%A %e %B %Y", mktime(0, 0, 0, 12, 22, 1978));
setlocale(LC_ALL, '');
// jeuves 22 diciembre 1978
?>
up
1
noog at libero dot it
13 years ago
On windows:
Control Panel->International Settings
You can set your locale and customize it
And locale-related PHP functions work perfectly
up
1
leif at neland dot dk
4 years ago
Regarding dash'es in locale, it appears they should be omitted entirely.

In /etc/locale.gen I have

da_DK.ISO-8859-15 ISO-8859-15

but locale -a gives

da_DK.iso885915

which is the format setlocale()  wants.

(Debian)
up
1
mvanbaak
7 years ago
To complement Sven K's tip about debian:

You can also install the package locales-all
That one holds all the locales there are in compiled form.
up
0
c dot madmax at gmail dot com
1 year ago
<?php

// the last foldername only contains a german umlaut (lower a with two dots = \xE4 in ISO-8859-1)
$path = "/home/madmax/photos_from_the_last_10_years/\xE4"

// php escapeshellarg remove characters (depends on locale settings)
// the following example will delete /home/madmax/photos_from_the_last_10_years/
// instead of /home/madmax/photos_from_the_last_10_years/ä

shell_exec(sprintf('rm -fr %s' escapeshellarg($path)));

// 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"))));
};

// delete /home/madmax/photos_from_the_last_10_years/ä
// and not /home/madmax/photos_from_the_last_10_years/
shell_exec(sprintf('rm -fr %s' binary_safe_escapeshellarg_that_is_not_totally_buggy_and_do_not_remove_f___ing_characters($path))); // binary safe!

?>
up
0
data dot ocean dot italia at gmail dot com
1 year ago
Instead, using php with IIS, I had to use this line for Italian language...

<?php setlocale(LC_ALL, 'Italian_Italy.1250'); ?>
up
0
Omer Sabic
4 years ago
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.
up
0
Un_passant
5 years ago
For debian/ubuntu, don't forget the charset UFT8.

// Works on Ubuntu 8.04 Server
setlocale(LC_TIME, 'fr_FR.UTF8', 'fr.UTF8', 'fr_FR.UTF-8', 'fr.UTF-8');
up
-1
RobQuist
8 months ago
In addition to russ, about getting / backing up the locale:
I'm using this in unit-tests. I wanted to test something based on locale, and reset the locale after the tests were done.

Yet there were some errors;
* setlocale doesn't like strings anymore. You need to use constants.
* Some contants don't exist anymore.

Here's an updated piece of code:

<?php
$originalLocales
= explode(";", setlocale(LC_ALL, 0));
setlocale(LC_ALL, 'nl_NL.UTF-8');

//Do something here

//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'
       
);

        foreach (
$originalLocales as $localeSetting) {
            if (
strpos($localeSetting, "=") !== false) {
                list (
$category, $locale) = explode("=", $localeSetting);
            } else {
               
$category = LC_ALL;
               
$locale   = $localeSetting;
            }

            if (!
in_array($category, $skipConstants)) {
               
setlocale(constant($category), $locale); //Using strings is deprecated.
           
}
        }
?>
up
0
michal dot kocarek at brainbox dot cz
6 years ago
Note about using UTF-8 locale charset on Windows systems:

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.

(written in time of PHP 5.2.4)
up
0
bryn AT lunarvis DOT com
6 years ago
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:

<?php
setlocale
(LC_TIME, 'cym');
$welsh= gmstrftime("%A, %B %Y - %H:%M",time());
echo
$welsh;
?>

The above certainly applies to Windows systems, but should also apply to Unix if the required support is installed.

Cheers,

Bryn.
up
0
ostapk
6 years ago
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
up
0
Periklis
6 years ago
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:
<?php
setlocale
(LC_TIME, 'greek');
setlocale(LC_CTYPE, 'greek');
?>
will not work, while
<?php
setlocale
(LC_CTYPE, 'greek');
setlocale(LC_TIME, 'greek');
?>
will do the job.
up
0
Edwin Martin
8 years ago
Debian users: Addition to Gabor Deri's note: if setlocale doesn't work in your locale and you're on Debian, and Gabor Deri's note doesn't work, you have to install the locales package.

As root, type: "apt-get install locales" and it will be installed.
up
0
glenn at europlan dot no
8 years ago
In most Unix/Linux system, you could use:

locale -a

This will list all available locales on the server.
up
0
pigmeu at pigmeu dot net
9 years ago
!!WARNING!!

The "locale" always depend on the server configuration.

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.

[]s

Pigmeu
up
0
mk at totu dot com
10 years ago
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
up
-1
tomas dot hampl at gmail dot com
3 years ago
On Linux, setlocale() depends on the installed locales. To see which locales are available to PHP, run this from the terminal:

"locale -a"

Provided list are all locales that are available on your server for PHP to use. To add a new one, run

locale-gen <locale name> (this may need sudo / root permissions), for example to add a Czech locale, run something like this:

"sudo locale-gen cs_CZ.utf8"

Then you can use this locale declaration:

setlocale(LC_ALL, 'cs_CZ.utf8');
up
-1
szepeshazi at gmail dot com
7 years ago
For those of you who are unfortunate enough (like me) to work in Windows environment, and try to set the locale to a language _and_ to UTF-8 charset, and were unable to do it, here is a workaround.

For example to output the date in hungarian with UTF-8 charset, this will work:

    $dateString = "%B %d., %A";
    setlocale(LC_ALL,'hungarian');
    $res=strftime($dateString);
    echo(iconv('ISO-8859-1', 'UTF-8', $res));

If anybody knows how to set the locale on Windows to the equivalent of "hu_HU.UTF-8" on unix, please do tell me.
up
-1
flavioacvalverde at gmail dot com
3 years ago
For Portugal I had to use

<?php setlocale(LC_ALL, 'Portuguese_Portugal.1252'); ?>

using php with IIS on Windows server.
up
-1
jonas at jonashaag dot de
6 years ago
On Ubuntu, you have to take p.e. "de_DE.utf8", all available languages you can get with:
    locale -a
up
-1
lifeless
7 years ago
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.
up
-1
misc dot anders at feder dot dk
13 years ago
Under FreeBSD, locale definitions are stored in the /usr/share/locale/ directory. Danish time formats and weekdays, for instance, are stored in /usr/share/locale/da_DK.ISO_8859-1/LC_TIME.
up
-2
Morgan Christiansson &lt;mog at linux dot nu&gt;
14 years ago
check /usr/share/locale/ if you want more info about the locale available with your *NIX box

there is also a file called /usr/share/locale/locale.alias with a list of aliases
such as swedish for sv_SE

so on all boxes i have accounts on (rh 6.0 and slack 3.4) you can just use setlocale("LC_ALL","swedish"); or other prefered language in plain english.

However, the weekdays were in all lowercase :(

Note: export LC_ALL=swedish made a lot of programs swedish for me, it's also possible to make them russian or japanese :)
up
-4
Arjon
6 years ago
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.
To Top