Гость
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / setlocale(LC_TIME, null) возвращает "C" / 3 сообщений из 3, страница 1 из 1
01.12.2016, 00:21
    #39358098
Cyrax_02
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
setlocale(LC_TIME, null) возвращает "C"
Debian 8 + php 5.6 . В системе установлены все необходимые локали:
автор locale -a
C
C.UTF-8
en_US.utf8
POSIX
ru_RU
ru_RU.cp1251
ru_RU.iso88595
ru_RU.koi8r
ru_RU.utf8
russian
автор locale
LANG=ru_RU.UTF-8
LANGUAGE=ru_RU:ru
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=ru_RU.UTF-8
Далее в php-коде проверяю:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
setlocale(LC_TIME, 'en_US.UTF-8');
die(strftime('%b %d, %Y %I:%M:%S %p',time()));     // Dec 01, 2016 12:11:27 AM
// setlocale(LC_TIME, null)     // C
// setlocale(LC_ALL, null)     // C

setlocale(LC_TIME, 'ru_RU.UTF-8');
die(strftime('%b %d, %Y %I:%M:%S %p',time()));     // дек 01, 2016 12:06:22 
// setlocale(LC_TIME, null)     // C
// setlocale(LC_ALL, null)     // C


В этом коде в обоих случаях указываемые локали корректно применяются.
Но при этом " setlocale(LC_ALL, null) " в обоих случаях возвращает локаль "C". Почему ?

Согласно справке :
авторЕсли в качестве locale передана пустая строка "" или NULL , имена локалей будут взяты из одноименных переменных окружения или переменной с именем "LANG" .
Если в качестве locale передан NULL или "0", локаль изменена не будет, а будет возвращено текущее значение.В данном случае мы явно устанавливаем локаль LC_TIME , проверяем, что она корректно установилась (корректно используется функцией strftime ) и тут же получаем её значение - но получаем "C". Почему ?
...
Рейтинг: 0 / 0
01.12.2016, 21:48
    #39358936
Cyrax_02
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
setlocale(LC_TIME, null) возвращает "C"
Ну вот и разобрались. Проверил и в Debian , и в Windows - сабжевый артефакт себя одинаково проявляет и в php 5.4 , и в php 5.6 .
В справке функция setlocale описана неправильно. Вернее, русскоязычный перевод включает отсебячину (про null ).

В справке в русском варианте написано:
авторЕсли в качестве locale передана пустая строка "" или NULL, имена локалей будут взяты из одноименных переменных окружения или переменной с именем "LANG".
Если в качестве locale передан NULL или "0" , локаль изменена не будет, а будет возвращено текущее значение. Далее смотрим англоязычный вариант:авторIf locale is NULL or the empty string "", the locale names will be set from the values of environment variables with the same names as the above categories, or from "LANG".
If locale is "0" , the locale setting is not affected, only the current setting is returned.Т.е., согласно англоязычному (оригинальному) варианту, при использовании null локаль будет изменена (так же, как и при использовании пустой строки). И возвращена будет не текущая локаль, а изменённая. С этим разобрались.

Далее. В обоих вариантах перевода указано, что при использовании "" (а также при использовании null , как мы только что выяснили) будет установлена и возвращена локаль, взятая из переменных окружения или из Lang. Если речь идёт о переменных окружения операционной системы, то это не правда. По крайней мере, для php 5.4 и выше. А именно: при использовании "" или null функция устанавливает и возвращает системную локаль по умолчанию - ту, которая применяется в операционной системе сразу после установки до каких-либо настроек локалей (в Linux - это 7-битная англоязычная локаль "С", в Windows - "Russian_Russia.1251"). Независимо от того, какая локаль установлена на уровне переменных окружения.

---
http://www.navioo.com/php/docs/function.setlocale.php When i tried to get the current locale (e.g. after i set the lang to german with setlocale(LC_ALL, 'de_DE'); ), the following did not work on my suse linux 9.0-box:
$currentLocale = setlocale(LC_ALL, NULL);
This code did a reset to the server-setting .
$currentLocale = setlocale(LC_ALL, 0); works perfectly for me, but the manual says NULL and 0 are equal in this case, but NULL seems to act like "" .
...
Рейтинг: 0 / 0
01.12.2016, 22:10
    #39358949
Cyrax_02
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
setlocale(LC_TIME, null) возвращает "C"
Остаются без объяснения следующие факты :
1. В англоязычных комментариях к справке по функции setlocale приводятся рабочие фрагменты кода, в которых для получения текущей локали используется параметр null , а не 0.
2. Практически все форумные и сайтовые движки (CMS) для получения текущей локали используют параметр null , а не 0. В итоге их код де факто является нерабочим.

Текущую картину можно объяснить так :
1. Изначально (до версии php 5.4 ) текущую локаль можно было получить и с параметром 0, и с параметром null . Но начиная с версии php 5.4 - только с параметром 0. При этом оригинальная (англоязычная) справка была откорректирована, а русскоязычный перевод остался без изменений.
2. В момент перевода справки на русский язык было обнаружено, что и при использовании параметра null функция также возвращает текущую локаль (как и при использовании 0 ). В итоге в русском переводе рядом с 0 был приписан и null . Но с версии php 5.4 null перестал работать как 0 . Но текущее предположение не объясняет наличие в комментариях к официальной справке рабочих фрагментов кода, в которых для получения текущей локали используется параметр null .

Склоняюсь к 1-му варианту.

P.S . Для получения текущей локали (без изменения оной) можно использовать и числовой параметр 0, и строковый "0".
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / setlocale(LC_TIME, null) возвращает "C" / 3 сообщений из 3, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]