2012-04-16 16 views
10

Estoy usando códigos ISO 3166-1-alpha 2 para pasar a una aplicación para recuperar un feed localizado, p./feeds/us para los Estados Unidos. Tengo una instrucción switch que sirve un feed basado en ese country_code.¿Existe una manera simple de obtener el código de idioma de un código de país en PHP

¿Hay alguna forma de convertir ese código de dos dígitos al código de idioma, p. en_US? Me pregunto si hay una biblioteca/función/estándar para hacer esto en PHP o si necesito construir mi propia matriz.

+2

Qué código de lenguaje debe "CH" usar? "EN"? "NO"? –

+0

Eche un vistazo a la nueva lista, la lista proporcionada en la respuesta está desactualizada. este contiene 422 - 460 entradas. http://msdn.microsoft.com/en-us/library/cc233968.aspx –

+0

Iba a sugerir que si su objetivo es utilizar la configuración regional para formatear la moneda para un mercado local, existe una estrategia que lo HACKS: –

Respuesta

12

Como han señalado otros, no existe una función incorporada ya que es probable debido a la realidad de muchos países que tienen varios idiomas. Desafortunadamente, no puedo apuntarlo a una biblioteca que hace esto, pero seguí adelante y escribí una pequeña función que hace lo que quiere.

Existen dos advertencias, una de las cuales es que si no se proporciona un idioma, solo seleccionará la primera configuración regional de la lista. Para evitar esto, tendrías que poner algo de lógica alrededor de la llamada de función para proporcionarle el lenguaje apropiado. La otra es que necesita tener instalado php5-intl.

<?php 

/** 
/* Returns a locale from a country code that is provided. 
/* 
/* @param $country_code ISO 3166-2-alpha 2 country code 
/* @param $language_code ISO 639-1-alpha 2 language code 
/* @returns a locale, formatted like en_US, or null if not found 
/**/ 
function country_code_to_locale($country_code, $language_code = '') 
{ 
    // Locale list taken from: 
    // http://stackoverflow.com/questions/3191664/ 
    // list-of-all-locales-and-their-short-codes 
    $locales = array('af-ZA', 
        'am-ET', 
        'ar-AE', 
        'ar-BH', 
        'ar-DZ', 
        'ar-EG', 
        'ar-IQ', 
        'ar-JO', 
        'ar-KW', 
        'ar-LB', 
        'ar-LY', 
        'ar-MA', 
        'arn-CL', 
        'ar-OM', 
        'ar-QA', 
        'ar-SA', 
        'ar-SY', 
        'ar-TN', 
        'ar-YE', 
        'as-IN', 
        'az-Cyrl-AZ', 
        'az-Latn-AZ', 
        'ba-RU', 
        'be-BY', 
        'bg-BG', 
        'bn-BD', 
        'bn-IN', 
        'bo-CN', 
        'br-FR', 
        'bs-Cyrl-BA', 
        'bs-Latn-BA', 
        'ca-ES', 
        'co-FR', 
        'cs-CZ', 
        'cy-GB', 
        'da-DK', 
        'de-AT', 
        'de-CH', 
        'de-DE', 
        'de-LI', 
        'de-LU', 
        'dsb-DE', 
        'dv-MV', 
        'el-GR', 
        'en-029', 
        'en-AU', 
        'en-BZ', 
        'en-CA', 
        'en-GB', 
        'en-IE', 
        'en-IN', 
        'en-JM', 
        'en-MY', 
        'en-NZ', 
        'en-PH', 
        'en-SG', 
        'en-TT', 
        'en-US', 
        'en-ZA', 
        'en-ZW', 
        'es-AR', 
        'es-BO', 
        'es-CL', 
        'es-CO', 
        'es-CR', 
        'es-DO', 
        'es-EC', 
        'es-ES', 
        'es-GT', 
        'es-HN', 
        'es-MX', 
        'es-NI', 
        'es-PA', 
        'es-PE', 
        'es-PR', 
        'es-PY', 
        'es-SV', 
        'es-US', 
        'es-UY', 
        'es-VE', 
        'et-EE', 
        'eu-ES', 
        'fa-IR', 
        'fi-FI', 
        'fil-PH', 
        'fo-FO', 
        'fr-BE', 
        'fr-CA', 
        'fr-CH', 
        'fr-FR', 
        'fr-LU', 
        'fr-MC', 
        'fy-NL', 
        'ga-IE', 
        'gd-GB', 
        'gl-ES', 
        'gsw-FR', 
        'gu-IN', 
        'ha-Latn-NG', 
        'he-IL', 
        'hi-IN', 
        'hr-BA', 
        'hr-HR', 
        'hsb-DE', 
        'hu-HU', 
        'hy-AM', 
        'id-ID', 
        'ig-NG', 
        'ii-CN', 
        'is-IS', 
        'it-CH', 
        'it-IT', 
        'iu-Cans-CA', 
        'iu-Latn-CA', 
        'ja-JP', 
        'ka-GE', 
        'kk-KZ', 
        'kl-GL', 
        'km-KH', 
        'kn-IN', 
        'kok-IN', 
        'ko-KR', 
        'ky-KG', 
        'lb-LU', 
        'lo-LA', 
        'lt-LT', 
        'lv-LV', 
        'mi-NZ', 
        'mk-MK', 
        'ml-IN', 
        'mn-MN', 
        'mn-Mong-CN', 
        'moh-CA', 
        'mr-IN', 
        'ms-BN', 
        'ms-MY', 
        'mt-MT', 
        'nb-NO', 
        'ne-NP', 
        'nl-BE', 
        'nl-NL', 
        'nn-NO', 
        'nso-ZA', 
        'oc-FR', 
        'or-IN', 
        'pa-IN', 
        'pl-PL', 
        'prs-AF', 
        'ps-AF', 
        'pt-BR', 
        'pt-PT', 
        'qut-GT', 
        'quz-BO', 
        'quz-EC', 
        'quz-PE', 
        'rm-CH', 
        'ro-RO', 
        'ru-RU', 
        'rw-RW', 
        'sah-RU', 
        'sa-IN', 
        'se-FI', 
        'se-NO', 
        'se-SE', 
        'si-LK', 
        'sk-SK', 
        'sl-SI', 
        'sma-NO', 
        'sma-SE', 
        'smj-NO', 
        'smj-SE', 
        'smn-FI', 
        'sms-FI', 
        'sq-AL', 
        'sr-Cyrl-BA', 
        'sr-Cyrl-CS', 
        'sr-Cyrl-ME', 
        'sr-Cyrl-RS', 
        'sr-Latn-BA', 
        'sr-Latn-CS', 
        'sr-Latn-ME', 
        'sr-Latn-RS', 
        'sv-FI', 
        'sv-SE', 
        'sw-KE', 
        'syr-SY', 
        'ta-IN', 
        'te-IN', 
        'tg-Cyrl-TJ', 
        'th-TH', 
        'tk-TM', 
        'tn-ZA', 
        'tr-TR', 
        'tt-RU', 
        'tzm-Latn-DZ', 
        'ug-CN', 
        'uk-UA', 
        'ur-PK', 
        'uz-Cyrl-UZ', 
        'uz-Latn-UZ', 
        'vi-VN', 
        'wo-SN', 
        'xh-ZA', 
        'yo-NG', 
        'zh-CN', 
        'zh-HK', 
        'zh-MO', 
        'zh-SG', 
        'zh-TW', 
        'zu-ZA',); 

    foreach ($locales as $locale) 
    { 
     $locale_region = locale_get_region($locale); 
     $locale_language = locale_get_primary_language($locale); 
     $locale_array = array('language' => $locale_language, 
          'region' => $locale_region); 

     if (strtoupper($country_code) == $locale_region && 
      $language_code == '') 
     { 
      return locale_compose($locale_array); 
     } 
     elseif (strtoupper($country_code) == $locale_region && 
       strtolower($language_code) == $locale_language) 
     { 
      return locale_compose($locale_array); 
     } 
    } 

    return null; 
} 
?> 
+1

Esta lista que está utilizando es antigua, eche un vistazo a la última revisión que contiene aproximadamente 422 - 460 entradas. http://msdn.microsoft.com/en-us/library/cc233968.aspx –

+0

Error fatal: llamada a la función indefinida locale_get_region() en el código del shell php – talsibony

+0

@talsibony ¿Tiene la extensión intl instalada? – alle

4

No se puede convertir automáticamente el código de país a código de idioma porque algunos países usan varios idiomas. Por otro lado, el sistema de localización del sistema operativo puede admitir múltiples variantes de un solo idioma para diferentes países (por ejemplo, en_GB vs en_US).

Por ejemplo, Suiza (CH) tiene tanto alemán como francés de uso común (64% y 20% de la población, según http://en.wikipedia.org/wiki/Switzerland). Si tiene que decidir un solo idioma para el código de país CH, cualquiera de esos idiomas podría tener sentido para algunas personas. Tenga en cuenta que algunas partes de Suiza solo usan el alemán o el francés como idioma oficial (pero no ambos, consulte http://en.wikipedia.org/wiki/File:Sprachen_CH_2000_EN.svg para obtener más información).

Si DEBE seleccionar un solo idioma para cada país, le sugiero que haga la selección a mano para cada país que admita. Para una implementación automática a medias, puede escanear a través de las localizaciones disponibles y seleccionar la primera que tenga el código de país coincidente después del guión bajo.

+0

mikko conoces el mundo y tienes una respuesta de calidad. Como suizo, quiero decir que en un país multilingüe es habitual elegir el condado en su idioma. Tomo Apple como ejemplo, cambian entre CH_de y CH_fr o se explican entre Schweiz-German y Suisse-Français. –

+0

@ endo.anaconda: supongo que se refería a de_CH y fr_CH. No sabía que usar el nombre del país seguido del nombre del idioma era un estilo de etiquetado común. Aquí en Finlandia, la localización sv_FI se conoce generalmente como "suomenruotsi", que se traduce directamente en "sueco de Finlandia" en lugar de "sueco de Finlandia" también. –

0

la answer from TheJF es bastante bueno, sin embargo hay algunas cuestiones (general) que me encontré:

  • su código volverá br-FR si llama country_code_to_locale("FR") - ahora br (Breton) se ni siquiera un lenguaje oficial según Wikipedia. Aunque fr-FR está en la lista, br-FR es el primero en la matriz. esto sucede con muchos otros países también.

  • muchas otras listas de localización están tratando de ser extremadamente completa y considerar todos los idiomas posibles

  • es difícil trazar la línea aquí, buenos ejemplos en los que sin duda desea mantener múltiples idiomas para un país son: Canadá y Suiza

fui con un enfoque sencillo :

  • Mantuve solo 1 idioma para la mayoría de los países, y dejé múltiples para algunos países como BE, CA, CH, ZA. Seguí es-US, pero no estoy seguro de eso (Wikipedia dice: Official languages: None at federal level)

  • también me quedé varios idiomas para los países que yo era demasiado perezoso para investigar o que utilice tanto, latino y cirílico

  • he añadido shuffle($locales); que aleatorizará la matriz, de modo que obtenemos locales aleatorios para países con varios idiomas. Tiene sentido para mi caso de uso, pero es posible que desee eliminar eso.

  • Para mi propósito, solo interesan los idiomas que tienen predominio relevante en la web. Esta lista no es completa ni correcta, sino pragmática.

Así que aquí está mi lista local:

$locales = array('af-ZA', 
       'am-ET', 
       'ar-AE', 
       'ar-BH', 
       'ar-DZ', 
       'ar-EG', 
       'ar-IQ', 
       'ar-JO', 
       'ar-KW', 
       'ar-LB', 
       'ar-LY', 
       'ar-MA', 
       'ar-OM', 
       'ar-QA', 
       'ar-SA', 
       'ar-SY', 
       'ar-TN', 
       'ar-YE', 
       'az-Cyrl-AZ', 
       'az-Latn-AZ', 
       'be-BY', 
       'bg-BG', 
       'bn-BD', 
       'bs-Cyrl-BA', 
       'bs-Latn-BA', 
       'cs-CZ', 
       'da-DK', 
       'de-AT', 
       'de-CH', 
       'de-DE', 
       'de-LI', 
       'de-LU', 
       'dv-MV', 
       'el-GR', 
       'en-AU', 
       'en-BZ', 
       'en-CA', 
       'en-GB', 
       'en-IE', 
       'en-JM', 
       'en-MY', 
       'en-NZ', 
       'en-SG', 
       'en-TT', 
       'en-US', 
       'en-ZA', 
       'en-ZW', 
       'es-AR', 
       'es-BO', 
       'es-CL', 
       'es-CO', 
       'es-CR', 
       'es-DO', 
       'es-EC', 
       'es-ES', 
       'es-GT', 
       'es-HN', 
       'es-MX', 
       'es-NI', 
       'es-PA', 
       'es-PE', 
       'es-PR', 
       'es-PY', 
       'es-SV', 
       'es-US', 
       'es-UY', 
       'es-VE', 
       'et-EE', 
       'fa-IR', 
       'fi-FI', 
       'fil-PH', 
       'fo-FO', 
       'fr-BE', 
       'fr-CA', 
       'fr-CH', 
       'fr-FR', 
       'fr-LU', 
       'fr-MC', 
       'he-IL', 
       'hi-IN', 
       'hr-BA', 
       'hr-HR', 
       'hu-HU', 
       'hy-AM', 
       'id-ID', 
       'ig-NG', 
       'is-IS', 
       'it-CH', 
       'it-IT', 
       'ja-JP', 
       'ka-GE', 
       'kk-KZ', 
       'kl-GL', 
       'km-KH', 
       'ko-KR', 
       'ky-KG', 
       'lb-LU', 
       'lo-LA', 
       'lt-LT', 
       'lv-LV', 
       'mi-NZ', 
       'mk-MK', 
       'mn-MN', 
       'ms-BN', 
       'ms-MY', 
       'mt-MT', 
       'nb-NO', 
       'ne-NP', 
       'nl-BE', 
       'nl-NL', 
       'pl-PL', 
       'prs-AF', 
       'ps-AF', 
       'pt-BR', 
       'pt-PT', 
       'ro-RO', 
       'ru-RU', 
       'rw-RW', 
       'sv-SE', 
       'si-LK', 
       'sk-SK', 
       'sl-SI', 
       'sq-AL', 
       'sr-Cyrl-BA', 
       'sr-Cyrl-CS', 
       'sr-Cyrl-ME', 
       'sr-Cyrl-RS', 
       'sr-Latn-BA', 
       'sr-Latn-CS', 
       'sr-Latn-ME', 
       'sr-Latn-RS', 
       'sw-KE', 
       'tg-Cyrl-TJ', 
       'th-TH', 
       'tk-TM', 
       'tr-TR', 
       'uk-UA', 
       'ur-PK', 
       'uz-Cyrl-UZ', 
       'uz-Latn-UZ', 
       'vi-VN', 
       'wo-SN', 
       'yo-NG', 
       'zh-CN', 
       'zh-HK', 
       'zh-MO', 
       'zh-SG', 
       'zh-TW'); 

y el código:

function country_code_to_locale($country_code) 
{ 
    $locales = ... 

    // randomize the array, such that we get random locales 
    // for countries with multiple languages (CA, CH) 
    shuffle($locales); 

    foreach ($locales as $locale) { 
     $locale_region = locale_get_region($locale); 

     if (strtoupper($country_code) == $locale_region) { 
      return $locale; 
     } 
    } 

    return "en-US"; 
} 
Cuestiones relacionadas