【问题标题】:PHP setlocale has no effectPHP setlocale 没有效果
【发布时间】:2012-06-10 05:09:14
【问题描述】:

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');

输出:

六月

而不是

六月

有什么建议吗?

  • 我没有 ssh 或其他 shell 访问权限。
  • 脚本正在 Linux 服务器上运行。

PHP 5.6 版

【问题讨论】:

  • 所以您尝试过其他版本的德语语言环境,例如setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'de', 'ge');?
  • 您应该通过检查setLocale的返回值来检查语言更改是否成功

标签: php date setlocale


【解决方案1】:

很可能是您运行脚本的服务器上没有安装德语语言环境 - 您是否具有对服务器的 shell 访问权限? 那就试试吧

locale -a

查看安装了哪些语言环境。也看看这里Is it feasible to rely on setlocale, and rely on locales being installed?

【讨论】:

  • 感谢您的及时回答,我不太可能没有 shell 访问权限。你的链接帮助了我:
  • 很抱歉,很高兴听到这个消息。您介意将我的答案标记为“答案”吗? :)
  • 如果您没有 shell 访问权限,您也可以尝试在 PHP:server('locale -a'); 中查找服务器上安装的语言环境的名称。
  • system('local -a'); 的调用将在本地基于 Windows 的开发环境中产生效果。因此,您将无法在 Win 上使用该解决方案。
  • 本地名称是否唯一?还是在 WIn7 上是“de”,在 Ubuntu 上是“ger”?
【解决方案2】:

您的代码是正确的。您可能只需要在运行脚本的服务器上安装正确的语言包。

在终端中,如果在运行命令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

然后,您将被允许使用 setlocale(...) 在 PHP 中将您的语言设置为这些,就像您所做的那样。


注意: 如果您在非 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.iso88591fr_CA.iso88591,您可以通过调用 setlocale(LC_ALL, 'fr_FR.iso88591'); 在 php 中使用它

【讨论】:

  • install-language-pack fr_FR 之后我需要使用@sephoy08 解决方案:setlocale(LC_ALL, 'fr_FR@euro', 'fr_FR', 'fra_fra');,它工作正常。谢谢
  • 非常有帮助。谢谢你的回答。
  • 在我的情况下安装相关的语言环境,给出这个命令“sudo /usr/share/locales/install-language-pack de_DE”是唯一对我有用的东西。注意前命令中的空格。
【解决方案3】:

对于那些来这里寻找 date() 的人不会本地化月份和工作日名称:

== 注意==

date() 只能返回英文的月/日名称,无法为您提供其他语言的翻译。

改用strftime()

【讨论】:

  • 终于找到了我来这里要找的东西。谢谢...尝试了所有的建议,但没有效果:(日期是这样的有点烦人
  • 使用strftime()
  • 2021 年更新,strftime() 自 PHP 8.1 起已弃用。
【解决方案4】:

试试这个:

date_default_timezone_set('Europe/Berlin');
$loc=setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');
echo strftime('%B');

【讨论】:

  • 谢谢!这对我在当地环境中的 Kirby 帮助很大!显然“de_DE”不起作用。 “deu_deu”成功了! c::set('locale','deu_deu');
【解决方案5】:

如果您没有对服务器的 shell 访问权限,此解决方案可能会有所帮助。

如果你有 shell 访问权限,那么Benjamin Seiller's answer 是最好的!

由于我没有任何其他可能性(shell),我通过使用IntlDateFormatter class 找到了仅使用 PHP 的解决方案。

<?php

// Example vars
$month = '6';
$year = '2014';

$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;

【讨论】:

    【解决方案6】:

    PHP manual page for 'setlocale' sais:

    注意:setlocale() 的返回值取决于 PHP 使用的系统 在跑。它准确地返回系统 setlocale 函数返回。

    如果你有 root 访问权限(debian),这里是解决方案:

    编辑

    /etc/locale.gen
    

    您可以添加/删除您需要使用的语言环境。保存文件后运行:

    locale-gen
    

    你应该没事。在我的服务器上,我必须重新启动 Apache 才能看到更改。

    【讨论】:

    • Apache 重启位是必不可少的,为此我浪费了一个小时。谢谢。
    【解决方案7】:

    在我的情况下这不起作用:

    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
    [...]
    

    【讨论】:

    • 我在网络上尝试了许多解决方案,但.. setlocale(LC_ALL, 'de_AT.utf-8'); 那条线挽救了生命。谢谢大佬
    【解决方案8】:
    apt-get install -y locales locales-all
    

    【讨论】:

    • 如此真实,如此简单。
    • 让它在我的 Ubuntu 20.04 服务器上运行!谢谢!
    【解决方案9】:

    这太痛苦了。

    我想将日期翻译成西班牙语,它在我的本地主机上工作,但不在服务器上(Ubuntu 18)。原来我没有正确的语言环境包。

    首先我检查了已安装的软件包以确保它们丢失

    locale -a
    

    然后我使用脚本安装了西班牙 UTF 的

    sudo pkg-reconfigure locales
    

    然后我花了好几个小时把头撞在桌子上,直到我意识到您需要重新启动 APACHE!

    sudo service apache2 restart
    

    我的故事就这样结束了。希望对您有所帮助。

    【讨论】:

    • 或者现在:sudo apt-get install language-pack-es
    • 捷克语包:sudo apt-get install language-pack-cs
    【解决方案10】:

    取决于底层操作系统 "de_DE" 和其他可能是错误的字符串。

    在 Windows 下参考这个列表:

    Win下通常是“DEU”或“GERMAN”。

    已经提到:

    在 Linux 下,您可以使用 shell 命令查看所有语言环境:

    locale -a
    

    【讨论】:

      【解决方案11】:

      PHP 在不同版本上对setlocale() 有奇怪的支持。

      以下测试是在 Windows(同一台机器)、Apache 2.4 x64(同一 Web 服务器)、PHP x64 TS(不同版本)上进行的。

      setlocale()返回:

      返回新的当前区域设置,如果您的平台上未实现区域设置功能、指定的区域设置不存在或类别名称无效,则返回 false

      所以,我将在不同版本的 PHP 上使用下面的测试。在 PHP 7.0 - 8.1 上测试。

      var_dump(setlocale(LC_ALL, 'en_US'));
      

      PHP 7.0、7.1 返回'en_US'
      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 或其他操作系统上结果可能不同。

      【讨论】:

        【解决方案12】:

        感谢 Rico Neitzel 的提示。 与其尝试格式化 php 日期,不如使用 strftime。 要查看您的语言中月份名称的前 3 个字母(例如 Dez 而不是 Dezembro 中的 Dec 而不是 12 月),请按照上面的语言环境安装说明进行操作,然后:

        date command: 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);
         } 
        }
        

        【讨论】:

          【解决方案13】:

          如果您使用的是 Red Hat 机器,您可以运行:

          localedef -v -c -i de_DE -f UTF-8 de_DE.UTF-8
          

          然后重启你的 Apache 服务器

          【讨论】:

            猜你喜欢
            • 2023-03-15
            • 1970-01-01
            • 1970-01-01
            • 2016-06-21
            • 1970-01-01
            • 2013-11-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多