IntCalendar在php中输出错误的locale

hgqdbh6s  于 11个月前  发布在  PHP
关注(0)|答案(3)|浏览(71)

我有下面的代码,我认为应该输出fr_FR作为区域设置,但由于某种原因输出en_US_POSIX(它在任何时区都这样做)。我做错了什么?

$loc = IntlCalendar::createInstance(new DateTimeZone('Europe/Paris'));
echo $loc->getLocale(Locale::VALID_LOCALE);

字符串
参考文献:https://www.php.net/manual/en/intlcalendar.createinstance.phphttps://www.php.net/manual/en/intlcalendar.getlocale.php
看起来这不是正确的方法(即使代码是有效的)-有没有更合适的方法来找到给定时区的“默认”区域设置?

klh5stk1

klh5stk11#

你可以从country (and country code) associated with a given timezone开始:

$userTimezone = new DateTimeZone('Europe/Paris');

$location = $userTimezone->getLocation();
/*
array(4) {
  ["country_code"]=>  string(2) "FR"
  ["latitude"]=>  float(48.866659999999996)
  ["longitude"]=>  float(2.3333299999999895)
  ["comments"]=>  string(0) ""
}
*/

$countryCode = $location['country_code'];

字符串
然后,您可以将这些信息与ICU库中的可用资源结合起来,以获得most-likely language of a given country code

// From @ausi's answer in https://stackoverflow.com/a/58512299/1456201
function getLanguage(string $country): string {
    $subtags = \ResourceBundle::create('likelySubtags', 'ICUDATA', false);
    $country = \Locale::canonicalize('und_'.$country);
    $locale = $subtags->get($country) ?: $subtags->get('und');
    return \Locale::getPrimaryLanguage($locale);
}


请注意,这并不适用于每个用户。这是一个不错的默认起点,但你应该总是询问用户他们的语言偏好是什么。

$possibleLocale = getLanguage($countryCode) . '_' . $countryCode; // fr_FR

li9yvcax

li9yvcax2#

您将时区设置为巴黎的时区。但你没有设定地点。它们是不同的东西。区域设置定义了语言和格式约定,而时区设置了将UTC转换为本地时间的规则。您所定义的内容适用于An American in Paris。这是一个有效的用例,尤其是在八月!
试试这个:

$loc = IntlCalendar::createInstance( new DateTimeZone( 'Europe/Paris' ), 'fr_FR' );
echo $loc->getLocale( Locale::VALID_LOCALE );

字符串

2jcobegt

2jcobegt3#

ICU/INTL区域设置不基于时区。它使用的默认值可以通过PHP ini设置或anywhere in your code设置。
为了使语言环境不同,您可以在INI设置中更改它(使用该INI文件运行的任何PHP脚本都将使用它)。或者,您可以在程式码中尽早指定(类似于使用INI设定),或在各种INTL类别方法中指定(例如,当您要使用使用者特定的区域设置,以使用者可能预期的方式显示格式化信息时),但不影响使用者特定部分以外的程式码:

// These values could be pulled from any source
// such as database.
$userLocale = 'fr_FR';
$userTimezone = new DateTimeZone('Europe/Paris');

$userCalendar = IntlCalendar::createInstance($userTimezone, $userLocale);
echo $userCalendar->getLocale(Locale::VALID_LOCALE); // fr_FR

字符串

相关问题