PHP setlocale has no effect

2019-01-04 11:20发布

The setlocale() function doesn't set the desired language (German).


The goal is to output month names.

This is my test code with trials so far:

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

Output:

June

instead of

Juni

Any suggestions?

  • I don't have ssh or other shell access.
  • The script is running on a linux server.

PHP version 5.6

9条回答
你好瞎i
2楼-- · 2019-01-04 12:00

Depending on the underlying OS "de_DE" and others maybe the wrong string.

Under Windows refer this lists:

Usually it's "DEU" or "GERMAN" under Win.

Already mentioned:

Under Linux you can see all locales with the shell command:

locale -a
查看更多
贪生不怕死
3楼-- · 2019-01-04 12:05

For those coming here looking for date() doesn't localize month and weekday names:

== Pay Attention ==

date() is only able to return month/day names in English and won't be able to give you translations for other languages.

查看更多
孤傲高冷的网名
4楼-- · 2019-01-04 12:06

Thanks to Rico Neitzel for the hint. Instead of trying to format php date, use strftime. To see the first 3 letters of month name in your language (Ex. Dez instead of Dec from Dezembro and not December), follow the locale instalation instructions above, and then:

date command: date('d M Y') // impossible to change from English

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);
 } 
}
查看更多
【Aperson】
5楼-- · 2019-01-04 12:08

Is is quite likely that the German locale is not installed on the server your running the script on - do you have shell access to the server? Then try

locale -a

to see which locales are installed. Also have a look here Is it feasible to rely on setlocale, and rely on locales being installed?

查看更多
混吃等死
6楼-- · 2019-01-04 12:09

If your are on a Red Hat machine you can run :

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

Then restart your Apache server

查看更多
够拽才男人
7楼-- · 2019-01-04 12:11

This solution might help if you don't have shell access to the server.

If you have shell access, then Benjamin Seiller's answer is the best!

As I don't have any other possibilities (shell), I've found a solution with only PHP by using the IntlDateFormatter class.

<?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;
查看更多
登录 后发表回答