Run locale with no arguments and you will see exactly which date, number and message formats your shell is quietly using right now. This walkthrough shows you how to read that output, test a different locale without touching anything, and set a lasting default in /etc/locale.conf. Allow about 10 minutes; you only need sudo for the last step.
Run locale without arguments. It prints the current value of each locale category, based on the environment seen by this process.
$ 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=C.UTF-8
Your list may be shorter or use different values. This guide was written against GNU locale from glibc 2.39 on Ubuntu, with Linux man-pages 6.7 as the local manual. Three categories matter most day to day:
LC_TIME controls date and time formats.LC_NUMERIC controls decimal and grouping conventions.LC_MESSAGES decides which language translated messages appear in.There is a trap hiding in this output. A non-empty LC_ALL overrides every individual LC_* variable, which in turn overrides LANG. If a test seems not to work, inspect the whole environment rather than changing LANG blindly:
$ env | grep -E '^(LANG|LANGUAGE|LC_)'
$ locale -k decimal_point thousands_sep date_fmt
The second command prints keyword names and values, which is easier to parse than the default output. Add -c when you also want the category name, for example locale -ck date_fmt.
Checkpoint: at this point you have only read the current process environment; nothing has been changed. Keep this output handy if you are diagnosing a script or service that formats data unexpectedly.
locale -a lists the locales available to the system. Names are exact, and aliases are not guaranteed to exist.
$ locale -a
C
C.utf8
POSIX
en_US.utf8
Use one of the names from your own output. Do not assume that en_GB.UTF-8, de_DE.UTF-8 or another familiar name exists just because a package or application mentions it. -m lists the available charmaps, which describe character sets:
$ locale -m
ANSI_X3.4-1968
UTF-8
The exact list is host-specific, so treat it as an inventory, not a guaranteed result.
Prefix a command with an environment assignment to try a locale without editing any configuration. This changes only that command's environment:
$ LC_TIME=en_US.utf8 locale -k date_fmt
date_fmt="%a %b %e %H:%M:%S %Z %Y"
To test several categories together, clear LC_ALL for the test if it is set, then supply the category you want:
$ env -u LC_ALL LANG=en_US.utf8 LC_NUMERIC=en_US.utf8 locale -ck decimal_point
LC_NUMERIC
decimal_point="."
This is a useful boundary for scripts: a command prefixed this way does not touch your login shell, other terminals, running services or the locale archive. It also fails cleanly when the requested locale is missing, so test before you commit to a durable change:
$ LC_TIME=locale-that-does-not-exist locale -k date_fmt
locale: Cannot set LC_TIME to default locale: No such file or directory
/etc/locale.conf is the systemd configuration file for system-wide locale settings. It is a newline-separated list of simple environment-like assignments; comments and empty lines are allowed, but shell features other than assignments are not. LC_ALL must not appear there.
Changing this file affects future users and services that inherit the system setting, but it does not rewrite the environment of shells already running. Back it up before editing:
$ sudo cp -a /etc/locale.conf /etc/locale.conf.bak
Edit the file as root and use a locale confirmed by locale -a. For example:
LANG=en_US.UTF-8
# Keep messages in English while changing other categories if needed
LC_MESSAGES=en_US.UTF-8
The systemd manual allows LANG, LANGUAGE and the individual LC_* categories, including LC_TIME and LC_NUMERIC. It specifically excludes LC_ALL, because that variable is meant as an overriding process-level setting, not a persistent default. Keep the file plain: no commands, no command substitutions, no export.
Check the saved file before logging out:
$ sed -n '1,80p' /etc/locale.conf
LANG=en_US.UTF-8
LC_MESSAGES=en_US.UTF-8
Open a new login session and run locale again. A service may run under its own environment or a kernel command-line override, so check the service separately if that is what you are solving. The setting is inherited by users and services unless they override or unset it.
Recovery: if a new session reports an unavailable locale, or applications stop starting with locale warnings, restore the backup and start a fresh session.
$ sudo cp -a /etc/locale.conf.bak /etc/locale.conf
If the backup is unavailable, remove only the lines you added and leave the file as a list of valid assignments. For a temporary workaround in the current shell, use export LANG=C.UTF-8 and unset conflicting category variables, or run the affected command with an explicit environment as in step 3. Do not use LC_ALL as a permanent repair: it can hide a bad category configuration and overrides deliberate per-category settings.
locale shows the settings your current process is using.locale -a confirms the exact locale name you intend to use./etc/locale.conf contains only valid assignments and no LC_ALL.