Все программы на *nix системах (не только python) стартуют, используя C (POSIX) locale до тех пор пока они не вызовут setlocale(LC_ALL, ''), чтобы активировать пользовательскую locale.

Если не хотите locale активировать для процесса, то можно использовать библиотеки, которые явно позволяют язык выбрать, такие как PyICU (пример использования)—есть полегче библиотеки, которые могут работать для конкретной задачи, например humanize:

>>> import datetime
>>> import humanize  # $ pip install humanize
>>> _ = humanize.i18n.activate('ru_RU')
>>> humanize.naturaltime(datetime.datetime.now())
'сейчас'

В: но почему же locale.getlocale() выдаёт ru_RU?

Я бы также ожидал, что-нибудь вроде (None, None) вместо ('ru_RU', 'UTF-8') до того как setlocale(LC_ALL, '') вызвано в программе. Из документации: "Returns the current setting for the given locale category" не очевидно, что пользовательские настройки из переменных окружения (LC_*, LANG) читаются, а не текущая локаль по умолчанию ("The POSIX locale is the default global locale at entry to main()") возвращается до вызова setlocale(LC_ALL, '').

locale модуль это тонкая обёртка вокруг соответствующей C функциональности, в частности, поведение может зависеть от платформы. Текущая реализация locale.getlocale() эквивалентна C setlocale(category, NULL), которая запрашивает текущую настройку для локали ("query the current global locale setting").

Почему "the current global locale setting" не равна "the default global locale" до вызова setlocale(LC_ALL, '') я не понимаю. Может дело в слове setting vs. locale, то есть текущая настройка до вызова setlocale(LC_ALL, '') берётся из переменных окружения (LC_*, etc), а текущая локаль до вызова setlocale(LC_ALL, ''), используемая strftime(), является C (как и положено). Но это чистая спекуляция с моей стороны.

Answer from jfs on Stack Overflow
🌐
Python
docs.python.org › 3 › library › locale.html
locale — Internationalization services
Source code: Lib/locale.py The locale module opens access to the POSIX locale database and functionality. The POSIX locale mechanism allows programmers to deal with certain cultural issues in an ap...
Top answer
1 of 1
7

Все программы на *nix системах (не только python) стартуют, используя C (POSIX) locale до тех пор пока они не вызовут setlocale(LC_ALL, ''), чтобы активировать пользовательскую locale.

Если не хотите locale активировать для процесса, то можно использовать библиотеки, которые явно позволяют язык выбрать, такие как PyICU (пример использования)—есть полегче библиотеки, которые могут работать для конкретной задачи, например humanize:

>>> import datetime
>>> import humanize  # $ pip install humanize
>>> _ = humanize.i18n.activate('ru_RU')
>>> humanize.naturaltime(datetime.datetime.now())
'сейчас'

В: но почему же locale.getlocale() выдаёт ru_RU?

Я бы также ожидал, что-нибудь вроде (None, None) вместо ('ru_RU', 'UTF-8') до того как setlocale(LC_ALL, '') вызвано в программе. Из документации: "Returns the current setting for the given locale category" не очевидно, что пользовательские настройки из переменных окружения (LC_*, LANG) читаются, а не текущая локаль по умолчанию ("The POSIX locale is the default global locale at entry to main()") возвращается до вызова setlocale(LC_ALL, '').

locale модуль это тонкая обёртка вокруг соответствующей C функциональности, в частности, поведение может зависеть от платформы. Текущая реализация locale.getlocale() эквивалентна C setlocale(category, NULL), которая запрашивает текущую настройку для локали ("query the current global locale setting").

Почему "the current global locale setting" не равна "the default global locale" до вызова setlocale(LC_ALL, '') я не понимаю. Может дело в слове setting vs. locale, то есть текущая настройка до вызова setlocale(LC_ALL, '') берётся из переменных окружения (LC_*, etc), а текущая локаль до вызова setlocale(LC_ALL, ''), используемая strftime(), является C (как и положено). Но это чистая спекуляция с моей стороны.

🌐
Metanit
metanit.com › python › tutorial › 6.3.php
Python | Модуль locale
February 4, 2022 - Если вместо конкретного кода в качестве второго параметра передается пустая строка, то Python будет использовать культуру, которая применяется на текущей рабочей машине. А с помощью функции getlocale() можно получить эту культуру: import locale locale.setlocale(locale.LC_ALL, "") number = 12345.6789 formatted = locale.format_string("%.02f", number) print(formatted) # 12345,68 print(locale.getlocale()) # ('Russian_Russia', '1251') - Windows # ('ru_RU', 'UTF-8') - MacOS ·
🌐
Miramik
dmitry.miramik.ru › 2011 › 07 › 12 › rabota-s-lokalyu-locale-v-python
Работа с локалью (locale) в Python
July 12, 2011 - До 50 000 товаров • Безлимит по трафику и месту на диске
🌐
Хабр Q&A
qna.habr.com › q › 1190
python, применение locale.setlocale — Хабр Q&A
October 8, 2010 - Единственная важная (имхо) разница между хостами — локаль: LANG=ru_RU.UTF-8 — на Mint LANG=en_US.UTF-8 — на Ubuntu Пробовал добавить в скрипт на минте import locale locale.setlocale(locale.LC_ALL, "en_US.UTF-8"), но никакого толку.
Top answer
1 of 2
11

Quick fix

Got it! янв has to be lower-case in CPython 2.7.12. Code (works in CPy 2.7.12 and CPy 3.4.5 on cygwin):

# coding=utf8
#timeData='[ 24-Янв-17 07:24 ]'
timeData='[ 24-янв-17 07:24 ]'    ### lower-case
import datetime
import locale
locale.setlocale(locale.LC_TIME, 'ru_RU.UTF-8')
result = datetime.datetime.strptime(timeData, u'[ %d-%b-%y  %H:%M ]')
print(result)

result:

2017-01-24 07:24:00

If I use the upper-case Янв, it works in Py 3, but in Py 2 it gives

ValueError: time data '[ 24-\xd0\xaf\xd0\xbd\xd0\xb2-17 07:24 ]' does not match format '[ %d-%b-%y  %H:%M ]'

General case

To handle this in general in Python 2, lower-case first (see this answer):

# coding=utf8
timeData=u'[ 24-Янв-17 07:24 ]'
       # ^ unicode data
import datetime
import locale
locale.setlocale(locale.LC_TIME, 'ru_RU.UTF-8')
print(timeData.lower())     # works OK
result = datetime.datetime.strptime(
    timeData.lower().encode('utf8'), u'[ %d-%b-%y  %H:%M ]')
    ##               ^^^^^^^^^^^^^^ back to a string
    ##       ^^^^^^^ lowercase
print(result)

Result:

[ 24-янв-17 07:24 ]
2017-01-24 07:24:00

I can't test it with your beautifulsoup code, but, in general, get Unicode data and then use the above.

Or, if at all possible, switch to Python 3 :) .

Explanation

So how did I figure this out? I went looking in the CPython source for the code to strptime (search). I found the handy _strptime module, containing class LocaleTime. I also found a mention of LocaleTime. To print the available month names, do this (added on to the end of the code under "Quick fix," above):

from _strptime import LocaleTime
lt = LocaleTime()
print(lt.a_month)    

a_month has the abbreviated month names per the source.

On Py3, that yields:

['', 'янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек']
      ^ lowercase!

On Py2, that yields:

['', '\xd1\x8f\xd0\xbd\xd0\xb2',

and a bunch more. Note that the first character is \xd1\x8f, and in your error message, \xd0\xaf doesn't match.

2 of 2
0

You can just change russian month name with english:

ru_to_eng_months = {'Янв': 'Jan', } # fill it with other months

def ru_to_eng_datetime(ru) -> string:
    s = ru.split('-')
    eng_month  = ru_to_eng_months[s[1]]
    return s[0] + '-' + eng_month + '-' + s[2]

s = u'[ 24-Янв-17 07:24 ]'
dateTime = ru_to_eng_datetime(s)
result = datetime.datetime.strptime(dateTime, u'[ %d-%b-%y  %H:%M ]')
print(result) # 2017-01-24 07:24:00
🌐
Stack Overflow
stackoverflow.com › questions › 67626716 › python-printing-in-russian-on-a-pc-using-a-different-locale
internationalization - Python printing in Russian on a PC using a different locale - Stack Overflow
... elif "Russian" in l[0] or "ru_" in l[0]: ru = gettext.translation('base', localedir='locales', languages=['ru']) ru.install() _ = ru.gettext import io sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8') sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8') in this way there are no runtime errors but the output does not seems to be russian, this should be the russian translation of "Hello Python!":
🌐
Msu
grep.cs.msu.ru › python3.8_RU › digitology.tech › docs › python_3 › library › locale.html
locale — Сервисы интернационализации — Документация Python 3.8.8
Доступные опции доступны в функции localeconv(). ... Категория локали для отображения сообщений. В настоящее время Python не поддерживает сообщения, учитывающие языковые ...
🌐
Python Documentation
docs-python.ru › standart-library › modul-locale-python › funktsija-setlocale-modulja-locale
Функция setlocale() модуля locale в Python
Функция `setlocale()` модуля `locale` изменяет настройку языкового стандарта для категории `category` если указан языковой стандарт `locale`. В случае ...
Find elsewhere
🌐
Runebook.dev
runebook.dev › ru › docs › python › library › locale
locale-службы интернационализации - Python
Доступные параметры доступны из функции localeconv() . ... Категория локали для отображения сообщений. В настоящее время Python не поддерживает сообщения, зависящие от локали приложения.
🌐
GitHub
github.com › python › cpython › blob › main › Lib › locale.py
cpython/Lib/locale.py at main · python/cpython
# Updated alias mapping with glibc 2.27 supported locales. # # These are the differences compared to the old mapping (Python 3.6.5 · # and older): # # updated 'ca_es@valencia' -> 'ca_ES.ISO8859-15@valencia' to 'ca_ES.UTF-8@valencia' # updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' # updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' # # SS 2025-02-04: # Updated alias mapping with glibc 2.41 supported locales and the latest ·
Author   python
🌐
Dzen
dzen.ru › a › Ytzk0ooAwCwYoXzk
Python. Модуль locale | Удалёнка
July 24, 2022 - We cannot provide a description for this page right now
🌐
Python
docs.python.org › 3.2 › library › locale.html
22.2. locale — Internationalization services — Python v3.2.6 documentation
The POSIX locale mechanism allows programmers to deal with certain cultural issues in an application, without requiring the programmer to know all the specifics of each country where the software is executed.
🌐
Lokalise
lokalise.com › home › date and time localization with formats | lokalise
Date and time localization with formats | Lokalise
1 week ago - Now, let’s see how to handle different locales in your Python apps. This is super useful when you want your dates and times to match the local language and formatting rules. To get started, you’ll need to import the locale module: ... Next, let’s switch the current locale to Russian (ru_RU) ...
🌐
Spec-zone
spec-zone.ru › python~3.5 › library › locale
Python 3.5 / locale - Spec-Zone.ru
Для работы Spec-Zone.ru требуется JavaScript, включите в настройках вашего браузера
🌐
Python
svn.python.org › projects › python › trunk › Lib › locale.py
locale.py
__all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error", "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm", "str", "atof", "atoi", "format", "format_string", "currency", "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY", "LC_NUMERIC", "LC_ALL", "CHAR_MAX"] try: from _locale import * except ImportError: # Locale emulation CHAR_MAX = 127 LC_ALL = 6 LC_COLLATE = 3 LC_CTYPE = 0 LC_MESSAGES = 5 LC_MONETARY = 4 LC_NUMERIC = 1 LC_TIME = 2 Error = ValueError def localeconv(): """ localeconv() -> dict.
🌐
Python Forum
python-forum.io › thread-19238.html
Russian version of Python
i remember reading somewhere a while back that there was a Russian version of Python that someone made that not only interacted in the Russian language but also changed the language itself so that keywords and names were to be coded in Russian using ...
🌐
Plotly
community.plotly.com › dash python
Localization Dash - Dash Python - Plotly Community Forum
July 16, 2022 - Hello all, I want to translate all my dash to russian. What I need to do for this? I tried some ways like external srcipts and ''https://cdn.plot.ly/plotly-locale-ru-latest.js" but it doesn’t work
🌐
Python
wiki.python.org › moin › Languages › Russian
Languages/Russian - Python Wiki
General Python information in the Russian language provided by Zaur Shibzoukhov.