9

So I've been trying to set the Python locale. I want to because I want to use the weekday name in local language (using strftime('%A')). But currently the weekday is printed in English even though I tried setting the locale several ways. I am running this on a RPi2 with Ubuntu Mate.

I have tried the solutions in this topic What is the correct way to set Python's locale on Windows?

I tried explicitly setting locale to nl_NL.utf8:

$> locale -a
$> python3
>>> import locale
>>> locale.setlocale(locale.LC_ALL,'nl_NL.utf-8')

I also tried setting an empty string, a suggested in the last answer:

>>> locale.setlocale(locale.LC_ALL, '')

In both cases when I try

>>> locale.getlocale()

I see nl_NL.utf8

But I still get the weekday in English! Haven't been able to find much about this on the internetz except for the above topic and I couldn't get this fixed.


Edit:

I have tried all 3 options. The first one returns a weird result:

~/Documenten$ python3
Python 3.4.3+ (default, Oct 14 2015, 16:03:50) 
[GCC 5.2.1 20151010] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getlocale(locale.LC_TIME)
(None, None)
>>> locale.setlocale(locale.LC_TIME, 'nl_NL.utf-8')
'nl_NL.utf-8'
>>> locale.getlocale(locale.LC_TIME)
('nl_NL', 'UTF-8')
>>> exit()
jeffrey@jeffrey-desktop:~/Documenten$ python3
Python 3.4.3+ (default, Oct 14 2015, 16:03:50) 
[GCC 5.2.1 20151010] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getlocale(locale.LC_TIME)
(None, None)

It seems like nothing is saved. Am I wrong in assuming you set your locale once and then the system will remember this? The second option:

~/Documenten$ python3
Python 3.4.3+ (default, Oct 14 2015, 16:03:50) 
[GCC 5.2.1 20151010] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import calendar
>>> calendar.day_name[2]
'Wednesday'
>>> import locale
>>> locale.nl_langinfo(locale.DAY_2)
'Monday'

Even though I am trying to get a Dutch weekday name I still get an English name in return. Besides that this method starts counting from sunday and not monday. Am I doing anything wrong? The third suggestion got me my weekday name, thanks! But I'm still wondering why the first doesn't work? I am using this script on my own device and would like to work with a correct global locale.


Edit2:

yes, calling locale.setlocale() in Python does not affect future python processes. Configure environment variables instead, see How to set all locale settings in Ubuntu.

Ok! So that is why it didn't work. I assumed I had set the locale for any future use in Python, like an environment variable but then only for Python.

I have a bash script creating files and this Python script should delete it after some time (learning to code, didn't know Python when I wrote the Bash script). Bash's "date" method seems to pick up the locale some way or the other. I'll go ahead and see what I can fix for Python. This is what I see when I type $ locale:

LANG=nl_NL.UTF-8
LANGUAGE=nl:en
LC_CTYPE="nl_NL.UTF-8"
LC_NUMERIC="nl_NL.UTF-8"
LC_TIME="nl_NL.UTF-8"
LC_COLLATE="nl_NL.UTF-8"
LC_MONETARY="nl_NL.UTF-8"
LC_MESSAGES="nl_NL.UTF-8"
LC_PAPER="nl_NL.UTF-8"
LC_NAME="nl_NL.UTF-8"
LC_ADDRESS="nl_NL.UTF-8"
LC_TELEPHONE="nl_NL.UTF-8"
LC_MEASUREMENT="nl_NL.UTF-8"
LC_IDENTIFICATION="nl_NL.UTF-8"
LC_ALL=
Community
  • 1
  • 1
Jeffrey
  • 105
  • 1
  • 1
  • 8
  • That's odd - what version of Python are you running (`python -V`)? What does your environment have set (via the `env` command)? – wkl Jan 04 '16 at 20:04
  • `python3 -V` returns `Python 3.4.3+`. Using `env` returns `LANGUAGE=nl:en` – Jeffrey Jan 04 '16 at 20:06
  • You might want to do `sudo dpkg-reconfigure locales` and regenerate your locales. I still can't reproduce your particular issue of getting your weekday in English even after you've changed the locale. – wkl Jan 04 '16 at 20:15
  • what is `locale.getlocale(locale.LC_TIME)`? – jfs Jan 05 '16 at 03:58
  • try to limit your questions to a single issue (there could be several problems in your code but it is more useful for future readers if each separate issue is handled in a separate question). What is your current issue now that you understand that `locale.setlocale()` does not affect other processes on the system? Do you understand that you need to [call `setlocale()` to use non-C locale in the *current* process](http://stackoverflow.com/a/12168157/4279)? – jfs Jan 07 '16 at 03:58
  • Ok, thank you for that last link, I am not missing any links anymore. As I understand: Python by default uses a portable locale, If you want to use the environment locale you have to call setlocale, one option is to leave the value empty, then it will pick up the default environment locale. I just tested it and it works! Thanks a lot, really happy with this. – Jeffrey Jan 08 '16 at 16:38

1 Answers1

9

It seems like nothing is saved. Am I wrong in assuming you set your locale once and then the system will remember this

yes, calling locale.setlocale() in Python does not affect future python processes. Configure environment variables instead, see How to set all locale settings in Ubuntu.

Bash's "date" method seems to pick up the locale some way or the other.

date calls setlocale(LC_ALL, "") at the start i.e., you need to call setlocale() at least once per process to enable $LANG locale instead of C locale.


setlocale(LC_ALL, '') sets locale according to $LANG variable first, not $LANGUAGE (it is related but different: "The GNU gettext search path contains 'LC_ALL', 'LC_CTYPE', 'LANG' and 'LANGUAGE', in that order.").

It is enough to set LC_TIME category (on Ubuntu):

>>> import locale
>>> import time
>>> time.strftime('%A')
'Tuesday'
>>> locale.getlocale(locale.LC_TIME)
('en_US', 'UTF-8')
>>> locale.setlocale(locale.LC_TIME, 'ru_RU.UTF-8')
'ru_RU.UTF-8'
>>> time.strftime('%A')
'Вторник'
>>> locale.getlocale(locale.LC_TIME)
('ru_RU', 'UTF-8')

If setlocale() hasn't raised locale.Error: unsupported locale setting then the corresponding locale category is set successfully.

You could also get the weekday name knowing its position (in the same python session where the locale is changed):

>>> import calendar
>>> calendar.day_name[1]
'Вторник'
>>> locale.nl_langinfo(locale.DAY_3)
'Вторник'

A portable way, to print a weekday in a given locale without modifying a global state, is to use babel module:

>>> from datetime import date
>>> from babel.dates import format_date # $ pip install babel
>>> format_date(date.today(), format='EEEE', locale='en')
'Tuesday'
>>> format_date(date.today(), format='EEEE', locale='ru')
'вторник'
>>> format_date(date.today(), format='EEEE', locale='nl')
'dinsdag'
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670