В данной статье я покажу как работать с локалью — набором параметров, определяющий региональные настройки пользовательского интерфейса, такие как язык, страна, часовой пояс, набор символов и т. п. Напомню, что локаль задается в следующем формате:
<ЯЗЫК>_<ТЕРРИТОРИЯ>.<КОДИРОВКА>[@<МОДИФИКАТОРЫ>]
ЯЗЫК | Код языка по стандарту ISO 639 |
ТЕРРИТОРИЯ | Код страны по стандарту ISO 3166 |
КОДИРОВКА | Набор символов или идентификатор кодировки текста, как ISO-8859-1 или UTF-8 (список доступных выводится командой locale -m ) |
Список всех поддерживаемых (доступных для установки) локалей в текущей системе можно посмотреть командой:
# cat /usr/share/i18n/SUPPORTED
Посмотреть весь список установленных локалей можно командой:
# locale -a
C
C.UTF-8
POSIX
en_US.utf8
Так же, можно просто распечатать содержимое файла:
# cat /etc/locale.gen
en_US.UTF-8 UTF-8
Добавим русскую локаль, для этого в файл /etc/locale.gen добавим новую строку/раскомментируем ru_RU.UTF-8 и выполним команду:
# locale-gen
Generating locales (this might take a while)...
en_US.UTF-8... done
ru_RU.UTF-8... done
или просто выполним команду:
# locale-gen ru_RU.UTF-8
Generating locales (this might take a while)...
en_US.UTF-8... done
ru_RU.UTF-8... done
Да, есть в локали и такое понятие. Параметр category - это именованная константа, определяющая категорию функций, на которые будет влиять установка локали:
Давайте посмотрим текущие значения категорий локали:
# locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
Давайте посмотрим текущие значения категорий LC_TELEPHONE:
# locale -c LC_ADDRESS
LC_ADDRESS
%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N0
ANSI_X3.4-1968
Влияние локали
Теперь проверим, как переключать локаль и на что локаль влияет:
<?php
$float1 = 200.20;
$float2 = 2.5;echo setlocale(LC_ALL, 0);// C - это значит, что локаль в PHP не указан, поэтому будет использоваться локаль назначенная в операционной системе
echo (string)$float1;// 200.2 - обратите внимание на разделитель в виде точки, это присуще англоязычным странам
var_dump(bcdiv($float1, $float2, 2));// string(5) "80.08" - все отлично поделилосьsetlocale(LC_ALL, 'ru_RU.UTF-8');
echo setlocale(LC_ALL, 0);// ru_RU.UTF-8 - как видите, теперь PHP будет использовать новую локаль
echo (string)$float1;// 200,2 - обратите внимание на разделитель в виде запятой, это присуще русскоязычным странам
var_dump(bcdiv($float1, $float2, 2));// NULL - деление не произошло, потому что php привел float-значения к строке, в результате появились числа с запятыми, а числа с запятыми невалидны в PHP
Как же поделить числа используя локаль ru_RU.UTF-8, мой ответ такой:
setlocale(LC_NUMERIC,"en_US.UTF-8");
и надеяться, что никто не сменит category в процессе интерпритации стека вызовов PHP, либо юзать свою функцию bcdiv.
p.s. напомню, что изменить локаль в системе можно с помощью команды localedef
p.s. 2: поймал ошибку вида:
Traceback (most recent call last): File "/usr/bin/pip", line 11, in sys.exit(main()) File "/usr/lib/python2.7/dist-packages/pip/__init__.py", line 215, in main locale.setlocale(locale.LC_ALL, '') File "/usr/lib/python2.7/locale.py", line 581, in setlocale return _setlocale(category, locale) locale.Error: unsupported locale setting
Решается добавлением локали - см. выше параграф "Добавим локаль"