In PHP, IntCalendar outputs wrong locale.
P粉553428780
P粉553428780 2023-07-28 12:49:22
0
2
624
<p>I have the following code, which I believe is supposed to output fr_FR as the locale, but for some reason it outputs en_US_POSIX (regardless of time zone). What did i do wrong? </p> <pre class="brush:php;toolbar:false;">$loc = IntlCalendar::createInstance(new DateTimeZone('Europe/Paris')); echo $loc->getLocale(Locale::VALID_LOCALE);</pre> <p>Reference links: https://www.php.net/manual/en/intlcalendar.createinstance.php and https://www.php.net/manual/en/intlcalendar.getlocale.php<br /> ;<br />Looks like this isn't the right approach (although the code is valid) - is there a more suitable way to find the "default" locale for a given time zone? </p><p><br /></p>
P粉553428780
P粉553428780

reply all(2)
P粉464088437

You set your time zone to that of Paris. But you didn't set the locale. They are different things. The locale defines the language and formatting conventions, while the time zone sets the rules for converting UTC to local time and back again. What you define applies to Americans in Paris. This is a valid use case, especially in August!

Please try the following code:


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

You can start by getting the associated country (and country code) from a given time zone:

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

You can then combine this information with the resources available in the ICU library to get the most likely language for 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);
}

Please note that this does not apply to every user. This is a good default starting point, but you should always ask the user for their language preference.

$possibleLocale = getLanguage($countryCode) . '_' . $countryCode; // fr_FR 
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template