PHP date - 获取本地语言的月份名称

32

我有这个函数的一部分,它给我英文月份名称。如何将它们翻译成我的本地语言(塞尔维亚语)?

$month_name = date('F', mktime(0, 0, 0, $i));

其中$i是月份的数字(取值为1-12)。另请参见PHP:mktime


2
strftime,并安装适当的语言环境,并将当前语言环境设置为塞尔维亚语。 - Wrikken
6个回答

27

你应该使用 setlocale() 函数:

setlocale(LC_TIME, 'fr_FR');
$month_name = date('F', mktime(0, 0, 0, $i));

在这种情况下,它会将其设置为法语。对于您的情况,应选择以下之一:

  1. sr_BA - 塞尔维亚语(黑山)
  2. sr_CS - 塞尔维亚语(塞尔维亚)
  3. sr_ME - 塞尔维亚语(塞尔维亚和黑山)

14
我的date函数不考虑本地化,但我的strftime函数可以。如果你的date函数考虑本地化……那你用的是哪个PHP版本? - Wrikken
4
请注意,setlocale 函数会设置整个进程的区域设置(在多线程情况下使用多线程时可能会导致意外行为)。线程安全的替代方案是 IntlDateFormatter - Matmarbon
4
这个解决方案是错误的。假设现在是2019年1月30日,如果使用没有第五和第六参数的mktime()函数,它将使用当前的日期和年份。因此,如果你想得到$i=2$(表示二月),结果会是三月,因为2019-02-30并不存在,它将被解释为三月的某一天。为了避免这个问题,可以使用例如:mktime(0, 0, 0, $i$, 1, 2019)。无论如何,不要使用这个解决方案,因为它会在某些特定日期给出错误的结果。Stackoverflow上有太多错误的答案了... - Maarten Bruins

23

你应该使用setlocale()strftime()函数:

setlocale(LC_TIME, 'sr_CS');
$month_name = strftime('%B', mktime(0, 0, 0, $i));

如果您使用setTimezone()并使用getTimestamp(),则datetime对象存在时区问题。 - Thanatos11th
这对我有用,但不幸的是在我的机器上setLocale()不影响date() - Adi Prasetyo
1
strftime() 在 PHP 8.1 中已被弃用。 - Picard

16

这里有一个使用IntlDateFormatter的例子。

$format = new IntlDateFormatter('sr_CS', IntlDateFormatter::NONE, 
              IntlDateFormatter::NONE, NULL, NULL, "MMM");
$monthName = datefmt_format($format, mktime(0, 0, 0, $i));

你好,请将语言环境更改为“en”,月份更改为11。然后它会显示12月而不是11月。你能指导一下吗? - Apoorva Shah

12

对于那些在德语(和de_DE)上有困难的人,请确保您使用正确的语言代码。登录到您的服务器并运行locale -a以查看所有可用的语言代码列表。对于我来说,它显示如下:

C
C.UTF-8
de_AT.utf8
de_BE.utf8
de_CH.utf8
de_DE.utf8
de_LI.utf8
de_LU.utf8
...

您需要使用其中之一的代码。

然后您可以使用:

date_default_timezone_set('Europe/Berlin');
setlocale(LC_ALL, 'de_DE.utf8');
$date_now = date('Y-m-d');
$month_available = strftime('%B %Y', strtotime($date_now));
$month_next = strftime('%B %Y', strtotime($date_now.' +1 month'));

并且"März 2020"等正确显示。


5
这个问题询问如何获取月份列表,我只看到了提示,没有完整的代码答案,因此:
如果您有IntlDateFormatter可用-在大多数情况下都可用,您可以在给定的区域设置中创建一个格式化程序,并重复将基于月份数字创建的日期推送到它。
// or any other locales like pl_PL, cs_CZ, fr_FR, zh, zh_Hans, ...
$locale = 'en_GB';
$dateFormatter = new IntlDateFormatter(
    $locale,
    IntlDateFormatter::LONG, // date type
    IntlDateFormatter::NONE  // time type
);
$dateFormatter->setPattern('LLLL'); // full month name with NO DECLENSION ;-)
$months_locale = [];
for ($month_number = 1; $month_number <= 12; ++$month_number) {
    $months_locale[] = $dateFormatter->format(
        // 'n' => month number with no leading zeros
        DateTime::createFromFormat('n', (string)$month_number)
    );
}
// test output
echo "<pre>";
var_dump($months_locale);
echo "</pre>";

注意:LLLL会处理不进行下降,但如果语言有大小写之分,则不会处理第一个字母的大小写。一个很好的例子是,你可以得到en_GB的January,但cs_CZ的leden。 如果您希望所有字母都小写,请使用mb_strtolower($month_name); - docs 如果您只想让第一个字母大写,请使用mb_convert_case($month_name, MB_CASE_TITLE, 'UTF-8'); - docs 始终使用mb_*函数或它们的变体来处理区域特定的字符串! 因此,不要使用ucfirst!

1

在设置区域设置时传递编码是个好主意:

 <?php    
 date_default_timezone_set('Europe/Belgrade');
 setlocale(LC_TIME, array('sr_CS.UTF-8', 'sr.UTF-8'));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接