103

I've written a web application for which the user interface is in Dutch. I use the system's date and time routines to format date strings in the application. However, the date strings that the system formats are in English but I want them in Dutch, so I need to set the system's locale. How do I do that on Debian? I tried setting LC_ALL=nl_NL but it doesn't seem to have any effect:

$ date
Sat Aug 15 14:31:31 UTC 2009
$ LC_ALL=nl_NL date
Sat Aug 15 14:31:36 UTC 2009

I remember that setting LC_ALL on my Ubuntu desktop system works fine. Do I need to install extra packages to make this work, or am I doing it entirely wrong?

Hongli Lai
  • 2,112
  • 4
  • 22
  • 27

8 Answers8

110

Edit /etc/default/locale and set the contents to:

LANG="nl_NL.UTF-8"

You can check which locales you currently have generated using:

locale -a

You can generate more by editing /etc/locale.gen and uncommenting the lines for the locales that you want to enable. Then you can generate them by running the command:

locale-gen

You can find a list of supported locales in /usr/share/i18n/SUPPORTED

There is more information available on the Debian wiki.

David Pashley
  • 23,151
  • 2
  • 41
  • 71
  • 9
    /var/lib/belocs/list doesn't exist. You need to edit /etc/locale.gen or run dpkg-reconfigure locales instead. – pgs Aug 16 '09 at 02:44
  • +1 this answer for describing locale-gen, but as per the previous comment, there's no such file as /var/lib/belocs/list on my system – telent Jul 12 '11 at 19:52
  • It took me 5 hours to find this answer, which ended up being perfect. Moreover, it allows to make aliases: en_US UTF-8 and it_IT UFT-8 allowed me to have my locales in UTF-8 by default, which is great if you have PHP code that depends on locales – Cec May 19 '17 at 08:25
  • Is there a command or package which can edit and set the contents of /etc/default/locale ? – Karl Morrison Feb 15 '18 at 12:27
  • See answer below from Czar. You can do it like: sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen – Tobias Gaertner Aug 30 '18 at 10:17
87

You may need to install the locales package. This will ask you which locales to generate. If it's already installed, then dpkg-reconfigure locales will let you generate more locales.

Alex
  • 476
  • 13
  • 35
pgs
  • 3,471
  • 18
  • 19
  • That only generates locales, not set the system default. – David Pashley Aug 15 '09 at 15:54
  • 17
    NO, the final question of dpkg-reconfigure locales is to select the default locale. – pgs Aug 16 '09 at 02:42
  • 2
    I had to run it with `sudo` as in `sudo dpkg-reconfigure locales`. – Alex Yursha Aug 23 '17 at 04:56
  • If it's a server accessed through ssh [the Debian wiki page on locales](https://wiki.debian.org/Locale#Standard) recommends leaving leave the default locale set to `NONE`. – Paul Rougieux Dec 13 '17 at 21:16
  • 1
    This was exactly what I needed: get all locales installed in just a few keystrokes. Thank you so much! – mehov Jun 14 '18 at 10:24
  • @PaulRougieux I also noticed the recommendation of setting it to `None` when using **ssh** but I wonder why?! I use `en_US.UTF-8` as system default and haven't experienced any issues with that... – TheStoryCoder Aug 03 '18 at 09:59
47

Answers here are incomplete as with most elsewhere. After piecing together information from a few places, what worked for me was to (1) make sure the locale I wanted was available (generate it if it wasn't) then (2) set locale related environment variables to desired locale.

In my case I needed en_US.UTF-8 programmatically (i.e. non-interactively) installed in a docker container. The ff accomplished what I need but it should work just fine in an interactive shell.

apt-get update

# Install locales package
apt-get install -y locales

# Uncomment en_US.UTF-8 for inclusion in generation
sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen

# Generate locale
locale-gen

# Export env vars
echo "export LC_ALL=en_US.UTF-8" >> ~/.bashrc
echo "export LANG=en_US.UTF-8" >> ~/.bashrc
echo "export LANGUAGE=en_US.UTF-8" >> ~/.bashrc

On the same shell, you will need to do source ~/.bashrc for the env vars to take effect immediately. You can check that locale has been configured correctly by invoking locale.

LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8

There were a lot of Q&A entries regarding this subject but only a few were actually helpful. Credit where credit is due:

Czar
  • 590
  • 4
  • 6
  • 1
    This worked for us when needing a locale set for a dotnet application running in the official Microsoft images. – Thorbjørn Ravn Andersen Nov 25 '19 at 15:26
  • 1
    This worked for me when setting up a Docker container. However after doing `locale-gen`, instead of adding env vars to the `~/.bashrc`, I did `update-locale LANG=en_US.utf8` as `root` user to set system-wide locale to new users. – wind39 May 14 '20 at 19:52
  • Thanks, and worth to mention many non us or default encodings for a given language or not written in a full form, but just like the abbreviations for that language-country without the encoding suffix , eg "sk_SK" instead of "sk_SK.ISO-8859-2". And if it has a suffix for a non default encoding, it has to contain dashes like "ISO-8859-2" unlike provided by the output of command "ISO88592" – FantomX1 Aug 26 '21 at 11:45
9

None of these answers worked for me, on an LXC container installed with:

lxc-create -n sse-master -t download -n sse-master -- \
    -d debian -r jessie --arch i386

I always got the following output from locale-gen, i.e. not generating any locales (none listed):

$ sudo locale-gen
Generating locales (this might take a while)...
Generation complete.

Running dpkg-reconfigure locales and selecting some locales did not update /etc/locale.gen as I expected it to.

However, when I modified that file manually and uncommented the locales that I wanted, then locale-gen started working properly:

$ sudo locale-gen
Generating locales (this might take a while)...
  en_GB.UTF-8... done
  en_US.UTF-8... done
Generation complete.

I was also able to generate locales manually like this:

sudo localedef -i en_US -f UTF-8 en_US.UTF-8
sudo localedef -i en_GB -f UTF-8 en_GB.UTF-8

But this was not a permanent solution: I found that running locale-gen without the --keep-existing option will delete all such manually-generated locales, i.e. every locale not listed (and uncommented) in /etc/locale.gen.

qris
  • 1,151
  • 11
  • 18
4

For a web application, it might be better to use setlocale() inside the program, rather than requiring that the system default locale be set appropriately outside. Less loose ends that way.

SamB
  • 269
  • 2
  • 13
4

For those who, like me, on Ubuntu 14.04 LTS, have, somehow, no /etc/locale.gen file, you can add a new locale in /var/lib/locales/supported.d/local and then run :

sudo dpkg-reconfigure locales

You can also add the french (for example) locale this way (instead of editing /var/lib/locales/supported.d/local) :

sudo locale-gen fr_FR fr_FR.UTF-8

to add and generate the ISO-8859-1 and UTF-8 codesets of the fr_FR locale and finally type :

sudo dpkg-reconfigure locales

to finish the job

SebMa
  • 275
  • 1
  • 9
  • Thank you for mentioning that `supported.d/local` file, I found the unnecessary defines there. Took me way too long to find :/ – Avamander Jun 04 '20 at 13:24
2

Note: Some of the commands below require root privileges, consider the use of sudo.

Basic info

According to man locale-gen, locales are set in several files.

/etc/locale.gen

The main configuration file, which has a simple format: every line that is not empty and does not begin with a # is treated as a locale definition that is to be built.

/var/lib/locales/supported.d/

A directory containing locale.gen snippets provided by language-pack packages. Do not edit these manually, they will be overwritten on package upgrades.

Comprehensive details on locales at the Arch Wiki.

Checking locales and the locale

To check the (already) generated locales, run any of the following commands (with minor output differences).

locale -a
localedef --list-archive
localectl list-locales

To check the currently used locale, run any of the following commands (with minor output differences).

locale
localectl

Setting and generating (new) locales

Locales are typically set by uncommenting lines in /etc/locale.gen, after which running locale-gen is required.

nano /etc/locale.gen # uncomment desired lines (locales)
locale-gen

This will generate locales files for each uncommented line in /etc/locale.gen (and under /var/lib/locales/supported.d/), whether they were previously generated or not.

Alternatively, the command

locale-gen <locale>

will uncomment the corresponding line in locale-gen while generating the desired locale and only this one.

Removing locales

To remove locales in /etc/locale.gen, simply comment the desired lines and regenerate the locales using locale-gen. The command locale-gen --purge <locale> doesn't do what the modifier suggests.

To remove locales under /var/lib/locales/supported.d/ is trickier. Since any file /var/lib/locales/supported.d/<code> depends on the package language-pack-<code>-base, any change on the former will be restored when the latter is updated.

Workaround. To prevent changes under /var/lib/locales/supported.d/, set files in it with the "immutable (i)" attribute. So instead of removing files, empty them. For instance:

cd /var/lib/locales/supported.d/
rm <code> && touch <code> # <code> has been emptied
lsattr <code>    # regular attributes
chattr +i <code> # adding (+) immutable
lsattr <code>    # checking attributes

Setting the locale

Setting and generating locales does not set the system locale. Any of the following commands achieves this.

echo LANG=<code> | sudo tee /etc/locale.conf # reboot (might be ignored in Ubuntu)
localectl set-locale LANG=<code>
vitaminace33
  • 161
  • 4
1

But first you need to have needed language pack installed. On my German based VPS there was no english language pack pre-installed. So first you check that you have it installed:

aptitude install language-pack-en
valentt
  • 295
  • 3
  • 10