Locales on Ubuntu, languages configuration

Logo

Introduction

In most programming languages, it is convenient to use locale settings for displaying numbers, dates… Locale settings avoid developing functions to format data (month names, day names, currencies, etc…).

Python example :

import locale
import datetime

d = datetime.date(2020, 12, 10)

# US english format
locale.setlocale(locale.LC_ALL , 'en_US.utf8')

print(d.strftime('%B %e, %Y'))

v = locale.currency(1234567.89,grouping=True)
print(v)


# FR format
locale.setlocale(locale.LC_ALL , 'fr_FR.utf8')

print(d.strftime('%e %B %Y'))

v = locale.currency(1234567.89,grouping=True)
print(v)
  December 10, 2020
$1,234,567.89
10 décembre 2020
1 234 567,89 €

PHP example :

$d = DateTime::createFromFormat("Y-m-d", "2020-12-10");

// US english format
setlocale(LC_ALL, 'en_US.UTF-8');

echo strftime("%B %e, %Y", strtotime($d->format('Y-m-d')))."\n";

$v = numfmt_create('en_US.UTF-8', NumberFormatter::CURRENCY );
echo numfmt_format_currency($v, 1234567.89, 'USD')."\n";


// FR format
setlocale(LC_ALL, 'fr_FR.UTF-8');

echo strftime("%e %B %Y", strtotime($d->format('Y-m-d')))."\n";

$v = numfmt_create('fr_FR.UTF-8', NumberFormatter::CURRENCY );
echo numfmt_format_currency($v, 1234567.89, 'EUR')."\n";
  December 10, 2020
$1,234,567.89
10 décembre 2020
1 234 567,89 €

The major inconvenient : locale settings are OS dependent. If a requested locale is not installed on the OS where the program runs, formatting will fail or will fallback to default settings.

In this paper, a quick overview about locale settings on Ubuntu : installation, temporary or permanent modification.

Locale settings on Ubuntu

The current settings are displayed using locale command :

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

Use locale -a to list installed locales :

$ locale -a
C
C.UTF-8
POSIX
en_US.utf8

Installing a new locale

The supported locales for Ubuntu are stored in the file /usr/share/i18n/SUPPORTED :

/usr/share/i18n/SUPPORTED
…
de_DE.UTF-8 UTF-8       # German language, Germany, UTF-8 encoding
de_DE ISO-8859-1        # German language, Germany, ISO-8859-1 encoding
de_DE@euro ISO-8859-15  # German language, Germany, ISO-8859-15 encoding (+ euro symbol)
…
fr_CA.UTF-8 UTF-8       # French language, Canada, UTF-8 encoding
fr_CA ISO-8859-1        # French language, Canada, ISO-8859-1 encoding
…
fr_FR.UTF-8 UTF-8       # French language, France, UTF-8 encoding
fr_FR ISO-8859-1        # French language, France, ISO-8859-1 encoding
fr_FR@euro ISO-8859-15  # French language, France, ISO-8859-15 encoding (+ euro symbol)
…

Use locale-gen as root to install a new locale. Below, the french locale settings fr_FR.UTF-8 are installed :

root$ locale-gen fr_FR.UTF-8
Generating locales (this might take a while)...
  fr_FR.UTF-8... done
Generation complete.

The installation does not change the default locale settings. To check the installation :

$ locale -a | grep 'fr'
fr_FR.utf8

Changing locale settings

Temporarily

To change all locale settings for a shell session (dates, times, numbers…) :

$ export LANG=fr_FR.UTF-8
$ date
lundi 11 janvier 2021, 08:29:07 (UTC+0000)

For only one parameter, for example date/times :

$ export LC_TIME=fr_FR.UTF-8
$ date
lundi 11 janvier 2021, 08:29:07 (UTC+0000)

Permanently

To change permanently locale settings for a user : update $HOME/.bashrc or $HOME/.pam_environment files

$HOME/.bashrc
export LANG=fr_FR.UTF-8
export LC_MESSAGES=POSIX
$HOME/.pam_environment
LANG=fr_FR.UTF-8
LC_MESSAGES=POSIX

The option LC_MESSAGES=POSIX prevents system messages from being translated, generally preferable.

To change permanently locale settings for the Ubuntu server : as root, update /etc/default/locale or use update-locale command

/etc/default/locale
LANG=fr_FR.UTF-8
LC_MESSAGES=POSIX
update-locale
root$ update-locale LANG=fr_FR.UTF-8 LC_MESSAGES=POSIX

The file /etc/default/locale may not already exist if no locales are set on the system.