PHP setlocale не имеет никакого эффекта
setlocale()
функция не устанавливает желаемый язык (немецкий).
Цель состоит в том, чтобы вывести названия месяцев.
Это мой тестовый код с испытаниями:
<?php
date_default_timezone_set('Europe/Berlin');
setlocale(LC_ALL, 'de_DE.utf8');
// Or
setlocale(LC_ALL, 'de_DE@euro');
// Or
setlocale(LC_ALL, 'de_DE');
// Or
setlocale(LC_ALL, 'de');
// Or
setlocale(LC_ALL, 'ge');
echo strftime('%B');
Выход:
июнь
вместо
Juni
Какие-либо предложения?
- У меня нет доступа по ssh или другой оболочке.
- Скрипт работает на сервере Linux.
PHP версия 5.6
14 ответов
Это решение может помочь, если у вас нет доступа к серверу.
Если у вас есть доступ к оболочке, то ответ Бенджамина Сейллера самый лучший!
Поскольку у меня нет никаких других возможностей (оболочка), я нашел решение с использованием только PHP с использованием класса IntlDateFormatter.
<?php
// Example vars
$month = '6'; // 1-12
$year = '2014'; // four digit year
$fmt = new IntlDateFormatter('de_DE',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'Europe/Berlin',
IntlDateFormatter::GREGORIAN);
$lastMonth = mktime(0, 0, 0, $month -1, 1, $year);
$showLastMonth = $fmt->format($lastMonth);
echo $showLastMonth;
Вполне вероятно, что немецкий язык не установлен на сервере, на котором вы запускаете сценарий - есть ли у вас доступ к серверу? Тогда попробуй
locale -a
чтобы увидеть, какие локали установлены. Также посмотрите здесь. Можно ли полагаться на setlocale и полагаться на устанавливаемые локали?
Для тех, кто приезжает сюда, ищет date(), но не локализует названия месяца и дня недели:
== Обратите внимание ==
Функция date() может возвращать названия месяцев / дней только на английском языке и не может переводить переводы на другие языки.
Ваш код правильный. Возможно, вам просто нужно установить правильный языковой пакет на сервере, на котором вы запускаете скрипт.
В терминале, если нужный язык не указан при запуске команды sudo locale -a
тогда вам нужно будет установить его, выполнив следующую команду:
sudo /usr/share/locales/install-language-pack de_DE
(sudo
здесь необязательно, если у вашего пользователя есть права root)
Тогда, если вы дважды проверьте с sudo locale -a
Тебе следует увидеть de_DE.utf8
,
Если вы хотите установить пакет на французском языке, запустите
sudo /usr/share/locales/install-language-pack fr_FR
Тогда вам будет разрешено установить свой язык на них в PHP с помощью setlocale(...)
Точно так же, как ты это сделал.
Примечание. Если вы работаете не в UTF8-проекте, вам необходимо сгенерировать другие форматы из установленных пакетов. Вот как продолжить работу с Ubuntu (эта работа также работает и с Debian):
отредактируйте /var/lib/locales/supported.d/cs и добавьте следующие строки
fr_FR.iso88591 ISO-8859-1
fr_CA.iso88591 ISI-8859-1
и беги
sudo dpkg-reconfigure locales
Затем снова запустив sudo locale -a
вы должны увидеть оба fr_FR.iso88591 и fr_CA.iso88591 в списке, и вы можете использовать его в php, вызвав setlocale(LC_ALL, 'fr_FR.iso88591');
Попробуй это:
date_default_timezone_set('Europe/Berlin');
$loc=setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');
echo strftime('%B');
Это была такая боль.
Я хотел перевести даты на испанский, и он работал на моем локальном хосте, но не на сервере (Ubuntu 18). Оказалось, что у меня нет нужных пакетов локали.
Сначала я проверил установленные пакеты, чтобы убедиться, что они отсутствуют.
locale -a
Затем я установил испанский UTF, используя скрипт
sudo pkg-reconfigure locales
А потом я часами бился головой о стол, пока не понял, что ВАМ НУЖНО ПЕРЕЗАПУСКАТЬ APACHE!
sudo service apache2 restart
И это конец моей истории. Надеюсь, это поможет.
В моем случае это не работает:
setlocale(LC_ALL, 'de_AT'); // false
пока это работает:
Locale::setDefault('de_AT'); // true
и это работает:
setlocale(LC_ALL, 'de_AT.utf-8'); // true
Вывод языковой программы:
$ locale -a
[...]
C.UTF-8
de_AT.utf-8
de_DE.utf-8
en_AG
[...]
Страница руководства PHP для 'setlocale' говорит:
Примечание. Возвращаемое значение setlocale() зависит от системы, в которой работает PHP. Он возвращает именно то, что возвращает системная функция setlocale.
Если у вас есть root-доступ (debian), вот решение:
редактировать
/etc/locale.gen
Вы можете добавить / удалить, какие локали вам нужно использовать. После сохранения файла запустите:
locale-gen
и ты должен быть в порядке. На моем сервере мне пришлось перезапустить Apache, чтобы увидеть изменения.
В зависимости от базовой ОС "de_DE"
и другие, возможно, неправильная строка.
Под Windows ссылаются на эти списки:
- http://msdn.microsoft.com/en-us/library/39cwe7zf%28v=vs.90%29.aspx
- http://msdn.microsoft.com/en-us/library/cdax410z%28v=vs.90%29.aspx
Обычно это "DEU" или "НЕМЕЦКИЙ" под Win.
Уже упоминалось:
Под Linux вы можете увидеть все локали с помощью команды shell:
locale -a
PHP имеет странную поддержку в разных версиях.
Ниже приведены тесты для Windows (та же машина), Apache 2.4 x64 (тот же веб-сервер), PHP x64 TS (разные версии).
Возвращает новую текущую локаль или, если функциональность локали не реализована на вашей платформе, указанная локаль не существует или имя категории недопустимо.
Итак, я буду использовать приведенные ниже тесты на разных версиях PHP. Протестировано на PHP 7.0 - 8.1.
var_dump(setlocale(LC_ALL, 'en_US'));
PHP 7.0, 7.1 возвращают .
Возврат PHP 7.2+ (или новее)
false
.
var_dump(setlocale(LC_ALL, 'en-US'));
PHP 7.0+ возврат
'en-US'
.
И для тестирования с несколькими значениями, чтобы увидеть, какое из них будет принято
setlocale()
функция.
Я использую этот массив.
$locale = ['en_US.UTF-8', 'en-US.UTF-8', 'en.UTF-8', 'en-US', 'en_US', 'en'];
var_dump(setlocale(LC_ALL, $locale));
PHP 7.0, возврат 7.1
'en_US.UTF-8'
.
PHP 7.2+ возврат
'en-US.UTF-8'
.
Как видите, если бы PHP поддерживал
'en_US'
для старой версии это не означает, что она будет поддерживаться в новой версии.
В случае с OP, возможно, попробуйте использовать этот массив, чтобы увидеть, какая локаль будет принята.
$locale = ['de_DE.UTF-8', 'de-DE.UTF-8', 'de.UTF-8', 'de_DE', 'de-DE', 'de', 'ge'];
var_dump(setlocale(LC_ALL, $locale));
Результат может отличаться в Linux или другой ОС.
Спасибо Рико Нейцель за подсказку. Вместо того, чтобы пытаться форматировать дату php, используйте strftime. Чтобы увидеть первые 3 буквы названия месяца на вашем языке (например, Dez вместо Dec от Dezembro, а не декабря), следуйте приведенным выше инструкциям по установке локали, а затем:
команда date: date ('d M Y') // невозможно изменить с английского
setlocale( LC_ALL, "pt_BR"); // Portuguese, replace with your locale
echo strftime('%e %b %G');
result: "4 Dez 2016"
/**
* datelo funcion (date with locale)
* Credits: Sergio Abreu
* http://sites.sitesbr.net
* NOTE: Depend on availability of the locale in server.
*
*/
function datelo( $str, $locale='en_US', $time=null){
if( $time === null){ $time = time(); }
if ( preg_match("/[DlFM]/", $str)){
setlocale(LC_ALL, $locale);
$dict = array( 'd'=>'%d', 'D'=>'%a', 'j'=>'%e', 'l'=>'%A', 'N'=>'%u', 'w'=>'%w', 'F'=>'%B',
'm'=>'%m', 'M'=>'%b', 'Y'=>'%G', 'g'=>'%l', 'G'=>'%k', 'h'=>'%I', 'H'=>'%H', 'i'=>'%M',
's'=>'%S', 'S'=>'', 'z'=>'%j', 'n'=>'%m', ' '=>' ', '-'=>'-', '/'=>'/', ':'=>':', ','=>',');
$chars = preg_split("//", $str);
$nstr = '';
foreach ($chars as $c){
if ($c){ //skip empties
$nc = $dict[$c];
if( $c === 'n'){ // Fixes the extra zero
$nc = preg_replace("/^0+/", '', strftime( $nc));
}
elseif( $c === 'z'){ // Fixes the extra zero and decrease 1
$nc = preg_replace("/^0+/", '', strftime( $nc)); // 023 turns 23
$nc = intval($nc) - 1;
}
$nstr .= $nc;
}
}
return strftime( $nstr);
}else{ // not localized
return date( $str, $time);
}
}
Если вы используете Red Hat, вы можете запустить:
localedef -v -c -i de_DE -f UTF-8 de_DE.UTF-8
Затем перезагрузите сервер Apache
Я надеюсь, что это поможет php 7.4
Когда я попытался напечатать дату на испанском языке, она выдала мне английскую версию.
Итак, я печатаю в терминале все свои языковые пакеты:
# locale -a
это не дает мне никого для испанского, так что бегом:
# sudo /usr/share/locales/install-language-pack es_ES
и измените te setlocale в коде на:
<?php
setlocale (LC_TIME, "es_ES", "es_ES.iso88591", "spanish");
?>
после этого перезапустите службу php с помощью:
/etc/init.d/php7.4-fpm restart
вот и все