Clase CultureInfo

En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.

La clase CultureInfo proporciona información específica de la referencia cultural, como la lengua, la sublengua, el país o la región, el calendario y las convenciones asociadas a una referencia cultural determinada. Esta clase también proporciona acceso a instancias específicas de la referencia cultural de los objetos DateTimeFormatInfo, NumberFormatInfo, CompareInfo y TextInfo. Estos objetos contienen la información necesaria para operaciones específicas de referencia cultural, como el uso de mayúsculas y minúsculas, el formato de fechas y números y la comparación de cadenas. La clase CultureInfo se usa directa o indirectamente por clases que formatean, analizan o manipulan datos específicos de la referencia cultural, como String, DateTime, DateTimeOffset y los tipos numéricos.

Nombres e identificadores de referencia cultural

La clase CultureInfo especifica un nombre único para cada referencia cultural, que se basa en RFC 4646. El nombre es una combinación de un código de referencia cultural ISO 639 de dos o tres letras en minúsculas asociado con un idioma y un código de referencia cultural secundaria ISO 3166 de dos letras en mayúsculas asociado con un país o región. Además, para las aplicaciones que se ejecutan en Windows 10 o posterior, se admiten nombres de referencia cultural que corresponden a etiquetas de idioma BCP-47 válidas.

Nota:

Cuando se pasa un nombre de referencia cultural a un constructor de clase o a un método como CreateSpecificCulture o CultureInfo, las mayúsculas y minúsculas no son significativas.

El formato del nombre de referencia cultural basado en RFC 4646 es languagecode2-country/regioncode2, donde languagecode2 es el código de idioma de dos letras y country/regioncode2 es el código de subcultura de dos letras. Algunos ejemplos son ja-JP para japonés (Japón) y en-US para inglés (Estados Unidos). En casos donde un código de idioma de dos letras no está disponible, se usa un código de tres letras, tal y como se define en la ISO 639-3.

Algunos nombres de referencia cultural también especifican un script ISO 15924. Por ejemplo, Cyrl especifica el script cirílico y Latn especifica el script latino. Un nombre de referencia cultural que incluye un script usa el patrón languagecode2-scripttag-country/regioncode2. Un ejemplo de este tipo de nombre cultural es uz-Cyrl-UZ para uzbeko (cirílico, Uzbekistán). En los sistemas operativos Windows anteriores a Windows Vista, un nombre de referencia cultural que incluía un script usaba el patrón languagecode2-country/regioncode2-scripttag. Por ejemplo: uz-UZ-Cyrl para uzbeko (cirílico, Uzbekistán).

Una referencia cultural neutra solo se especifica mediante el código de idioma en minúsculas de dos letras. Por ejemplo, fr especifica la referencia cultural neutra para francés y de especifica la referencia cultural neutra para alemán.

Nota:

Hay dos nombres de referencia cultural que contradicen esta regla. Las referencias culturales chino (simplificado), denominadas zh-Hans, y chino (tradicional), denominadas zh-Hant, son referencias culturales neutras. Los nombres de referencia cultural representan el estándar actual y deberían usarse a menos que haya una razón para usar los nombres anteriores zh-CHS y zh-CHT.

Un identificador de referencia cultural es una abreviatura numérica internacional estándar y tiene los componentes necesarios para identificar de forma única una de las referencias culturales instaladas. La aplicación puede usar identificadores de referencia cultural predefinidos o definir identificadores personalizados.

Ciertos identificadores y nombres de referencia cultural predefinidos se usan por esta y otras clases en el espacio de nombres System.Globalization. Para obtener información detallada sobre referencias culturales en los sistemas Windows, consulte la columna Etiqueta de idioma en la lista de nombres de idioma o región admitidos por Windows. Los nombres de las referencias culturales siguen el estándar definido por BCP 47.

Los nombres e identificadores de referencia cultural representan solo un subconjunto de referencias culturales que se pueden encontrar en un equipo determinado. Los Service Pack o versiones de Windows pueden cambiar las referencias culturales disponibles. Las aplicaciones pueden agregar referencias culturales personalizadas mediante la clase CultureAndRegionInfoBuilder. Los usuarios pueden agregar sus propias referencias culturales personalizadas mediante la herramienta Microsoft Locale Builder. Microsoft Locale Builder se escribe en código administrado mediante la clase CultureAndRegionInfoBuilder.

Varios nombres distintos están estrechamente asociados a una referencia cultural, en particular los nombres asociados a los siguientes miembros de clase:

Referencias culturales invariables, neutras y específicas

Las referencias culturales se agrupan generalmente en tres conjuntos: referencias culturales invariables, referencias culturales neutras y referencias culturales específicas.

Una referencia cultural invariable no distingue la referencia cultural. La aplicación especifica la referencia cultural invariable por nombre mediante una cadena vacía ("") o por su identificador. InvariantCulture define una instancia de la referencia cultural invariable. Está asociado al idioma inglés, pero no a ningún país o región. Se usa en casi cualquier método del espacio de nombres Globalization que requiera una referencia cultural.

Una referencia cultural neutra es una referencia cultural asociada a un idioma, pero no a un país o región. Una referencia cultural específica es una referencia cultural asociada a un idioma y a un país o región. Por ejemplo, fr es el nombre neutro de la referencia cultural francesa y fr-FR es el nombre de la referencia cultural específica francesa (Francia). Tenga en cuenta que el chino (simplificado) y el chino (tradicional) también se consideran culturas neutras.

No se recomienda crear una instancia de una clase CompareInfo para una referencia cultural neutra porque los datos que contiene son arbitrarios. Para mostrar y ordenar datos, especifique el idioma y la región. Además, la propiedad Name de un objeto CompareInfo creado para una referencia cultural neutra devuelve solo el país y no incluye la región.

Las referencias culturales definidas tienen una jerarquía en la que el elemento primario de una referencia cultural específica es una referencia cultural neutra, mientras que el elemento primario de una referencia cultural neutra es la referencia cultural invariable. La propiedad Parent contiene la referencia cultural neutra asociada a una referencia cultural específica. Las referencias culturales personalizadas deberían definir la propiedad Parent conforme a este patrón.

Si los recursos de una referencia cultural específica no estuvieran disponibles en el sistema operativo, se usarán los recursos de la referencia cultural neutra asociada. Si los recursos de la referencia cultural neutra no estuvieran disponibles, se usarán los recursos insertados en el ensamblado principal. Para obtener más información sobre el proceso de reserva de recursos, consulte Empaquetado e implementación de recursos.

La lista de configuraciones regionales de la API de Windows es ligeramente diferente de la lista de referencias culturales admitidas por .NET. Si se requiriese interoperabilidad con Windows (por ejemplo: a través del mecanismo p/invoke) la aplicación debería usar una referencia cultural específica definida para el sistema operativo. El uso de la referencia cultural específica garantizará la coherencia con la configuración regional de Windows equivalente, que se identifica con un identificador de configuración regional que es el mismo que LCID.

Solo se puede crear un DateTimeFormatInfo o un NumberFormatInfo para la referencia cultural invariable o para referencias culturales específicas, pero no para referencias culturales neutras.

Si DateTimeFormatInfo.Calendar fuera TaiwanCalendar pero Thread.CurrentCulture no estuviera establecido en zh-TW, entonces DateTimeFormatInfo.NativeCalendarName, DateTimeFormatInfo.GetEraName y DateTimeFormatInfo.GetAbbreviatedEraName devolverán una cadena vacía ("").

Referencias culturales personalizadas

En Windows, es posible crear configuraciones regionales personalizadas. Para obtener más información, consulte Configuraciones regionales personalizadas.

CultureInfo y los datos de referencias culturales

.NET deriva sus datos de referencias culturales de una variedad de fuentes, en función de la implementación, la plataforma y la versión:

  • En todas las versiones de .NET (Core) que se ejecutan en plataformas Unix o Windows 10 y versiones posteriores, la biblioteca Componentes internacionales para Unicode (ICU) proporciona datos de referencias culturales. La versión específica de la biblioteca de ICU depende del sistema operativo individual.
  • En todas las versiones de .NET (Core) que se ejecutan en Windows 9 y versiones anteriores, el sistema operativo Windows proporciona datos de referencias culturales.
  • En .NET Framework 4 y versiones posteriores, el sistema operativo Windows proporciona datos de referencias culturales.

Debido a esto, es posible que una referencia cultural disponible en una implementación, plataforma o versión de .NET determinada no esté disponible en otra implementación, plataforma o versión de .NET.

Algunos objetos CultureInfo difieren en función de la plataforma subyacente. En concreto, zh-CN o chino (simplificado, China) y zh-TW o chino (tradicional, Taiwán), son referencias culturales disponibles en sistemas Windows, mientras que son referencias culturales con alias en sistemas Unix. "zh-CN" es un alias para la referencia cultural "zh-Hans-CN", mientras que "zh-TW" es un alias para la referencia cultural "zh-Hant-TW". Las referencias culturales con alias no se devuelven a través de llamadas al método GetCultures y podrían tener valores de propiedades diferentes, incluyendo referencias culturales Parent diferentes, que los de sus homólogos de Windows. En el caso de las referencias culturales zh-CN y zh-TW, estas diferencias incluyen lo siguiente:

  • En los sistemas Windows, la referencia cultural primaria de la referencia cultural "zh-CN" es "zh-Hans", mientras que la de "zh-TW" es "zh-Hant". La referencia cultural primaria de ambas es "zh". En los sistemas Unix, el elemento primario de ambas culturas es "zh". Esto significa que, si no se proporcionan recursos específicos de la referencia cultural para las referencias culturales "zh-CN" o "zh-TW", pero se proporcionan recursos para las referencias culturales neutras "zh-Hans" o "zh-Hant", la aplicación cargará los recursos para la referencia cultural neutra en Windows, pero no en Unix. En los sistemas Unix, es necesario establecer explícitamente el CurrentUICulture del subproceso en "zh-Hans" o "zh-Hant".

  • En los sistemas Windows, llamar a CultureInfo.Equals en una instancia que represente la referencia cultural "zh-CN" y pasarla a una instancia "zh-Hans-CN" devolverá true. En los sistemas Unix, la llamada de método devolverá false. Este comportamiento también se aplica al llamar a Equals en una instancia de "zh-TW" CultureInfo y pasarla a una instancia de "zh-Hant-Tw".

Datos de referencias culturales dinámicas

Excepto para referencias culturales invariables, los datos de las referencias culturales son dinámicos. Esto es así incluso para aquellas referencias culturales que sean predefinidas. Por ejemplo, los países o regiones adoptan nuevas monedas, cambian la pronunciación de las palabras o cambian el calendario preferencial, por lo que las definiciones de referencias culturales cambian para seguir esto. Las referencias culturales personalizadas están sujetas a cambios sin previo aviso, por lo que una referencia cultural específica podría invalidarse mediante una referencia cultural de reemplazo personalizada. Además, tal y como se describe a continuación, un usuario individual podría invalidar las preferencias sobre referencias culturales. Las aplicaciones siempre deberían obtener datos sobre referencias culturales en tiempo de ejecución.

Precaución

Al guardar datos, la aplicación debería usar la referencia cultural invariable, un formato binario o un formato específico independiente de la referencia cultural. Los datos guardados según los valores actuales asociados a una referencia cultural determinada distinta de la referencia cultural invariable, podrían volverse ilegibles o cambiar su significado si esa referencia cultural cambiase.

La referencia cultural actual y la referencia cultural de la interfaz de usuario actual

Cada subproceso de una aplicación .NET tiene una referencia cultural actual y una referencia cultural de interfaz de usuario actual. La referencia cultural actual determina las convenciones de formato para las fechas, horas, números y valores de moneda, el criterio de ordenación del texto, las convenciones de mayúsculas y minúsculas y las formas en que se comparan las cadenas. La referencia cultural de la interfaz de usuario actual se usa para recuperar recursos específicos de la referencia cultural en tiempo de ejecución.

Nota:

Para obtener más información sobre cómo se determinan la referencia cultural actual y la de la interfaz de usuario actual por subproceso, consulte la sección Referencias culturales y subprocesos. Para obtener más información sobre cómo se determinan la referencia cultural actual y la de la interfaz de usuario actual en subprocesos que se ejecuten en nuevos dominios de aplicación y en subprocesos que traspasen los límites del dominio de aplicación, consulte la sección Referencias culturales y dominios de aplicación. Para obtener más información sobre cómo se determinan la referencia cultural actual y la de la interfaz de usuario actual en subprocesos que realicen operaciones asincrónicas basadas en tareas, consulte la sección Referencias culturales y operaciones asincrónicas basadas en tareas.

Para obtener información más detallada sobre la referencia cultural actual, consulte la propiedad CultureInfo.CurrentCulture. Para obtener información más detallada sobre la referencia cultural de la interfaz de usuario actual, consulte el tema sobre la propiedad CultureInfo.CurrentUICulture.

Recuperación de la referencia cultural actual y de la referencia cultural de la interfaz de usuario actual

Es posible obtener un objeto CultureInfo que represente la referencia cultural actual de dos maneras:

En el ejemplo siguiente, se recuperan ambos valores de propiedad, se comparan para mostrar que son iguales y se muestra el nombre de la referencia cultural actual.

using System;
using System.Globalization;
using System.Threading;

public class CurrentCultureEx
{
    public static void Main()
    {
        CultureInfo culture1 = CultureInfo.CurrentCulture;
        CultureInfo culture2 = Thread.CurrentThread.CurrentCulture;
        Console.WriteLine("The current culture is {0}", culture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          culture1 == culture2);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The two CultureInfo objects are equal: True

Es posible obtener un objeto CultureInfo que represente la referencia cultural de la interfaz de usuario actual de dos maneras:

En el ejemplo siguiente, se recuperan ambos valores de propiedad, se comparan para mostrar que son iguales y se muestra el nombre de la referencia cultural de la interfaz de usuario actual.

using System;
using System.Globalization;
using System.Threading;

public class CurrentUIEx
{
    public static void Main()
    {
        CultureInfo uiCulture1 = CultureInfo.CurrentUICulture;
        CultureInfo uiCulture2 = Thread.CurrentThread.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", uiCulture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          uiCulture1 == uiCulture2);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The two CultureInfo objects are equal: True

Establecimiento de la referencia cultural actual y de la referencia cultural de la interfaz de usuario actual

Para cambiar la referencia cultural y la referencia cultural de la interfaz de usuario de un subproceso, haga lo siguiente:

  1. Cree una instancia de un objeto CultureInfo que represente esa referencia cultural llamando a un constructor de clase CultureInfo y pásele el nombre de la referencia cultural. El constructor CultureInfo(String) creará una instancia de un objeto CultureInfo que reflejará las invalidaciones del usuario en caso de que la nueva referencia cultural sea la misma que la referencia cultural actual de Windows. El constructor CultureInfo(String, Boolean) permite especificar si el objeto CultureInfo del que se acaba de crear la instancia reflejará las invalidaciones de usuario en caso de que la nueva referencia cultural sea la misma que la referencia cultural actual de Windows.

  2. Asigne el objeto CultureInfo a las propiedades CultureInfo.CurrentCulture o CultureInfo.CurrentUICulture en .NET Core y .NET Framework 4.6 y versiones posteriores.

En el ejemplo siguiente, se recupera la referencia cultural actual. Si no fuera francés (Francia) la referencia cultural, se cambiará la referencia cultural que haya por francés (Francia). De lo contrario, se cambiará la referencia cultural vigente por francés (Luxemburgo).

using System;
using System.Globalization;

public class ChangeEx1
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentCulture;
        Console.WriteLine("The current culture is {0}", current.Name);
        CultureInfo newCulture;
        if (current.Name.Equals("fr-FR"))
            newCulture = new CultureInfo("fr-LU");
        else
            newCulture = new CultureInfo("fr-FR");

        CultureInfo.CurrentCulture = newCulture;
        Console.WriteLine("The current culture is now {0}",
                          CultureInfo.CurrentCulture.Name);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The current culture is now fr-FR

En el ejemplo siguiente, se recupera la referencia cultural actual. Si no fuese esloveno (Eslovenia) la referencia cultural, se cambiará la referencia cultural que haya por esloveno (Eslovenia). De lo contrario, se cambiará la referencia cultural vigente por croata (Croacia).

using System;
using System.Globalization;

public class ChangeUICultureEx
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", current.Name);
        CultureInfo newUICulture;
        if (current.Name.Equals("sl-SI"))
            newUICulture = new CultureInfo("hr-HR");
        else
            newUICulture = new CultureInfo("sl-SI");

        CultureInfo.CurrentUICulture = newUICulture;
        Console.WriteLine("The current UI culture is now {0}",
                          CultureInfo.CurrentUICulture.Name);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The current UI culture is now sl-SI

Obtener todas las referencias culturales

Es posible recuperar una matriz de categorías específicas de referencias culturales o de todas las referencias culturales disponibles en el equipo local llamando al método GetCultures. Por ejemplo, podría recuperar referencias culturales personalizadas, referencias culturales específicas o referencias culturales neutras solamente o en combinación.

En el ejemplo siguiente, se llama al método GetCultures dos veces, primero con el miembro de enumeración System.Globalization.CultureTypes para recuperar todas las referencias culturales personalizadas y, a continuación, con el miembro de enumeración System.Globalization.CultureTypes para recuperar todas las referencias culturales de reemplazo.

using System;
using System.Globalization;

public class GetCulturesEx
{
    public static void Main()
    {
        // Get all custom cultures.
        CultureInfo[] custom = CultureInfo.GetCultures(CultureTypes.UserCustomCulture);
        if (custom.Length == 0)
        {
            Console.WriteLine("There are no user-defined custom cultures.");
        }
        else
        {
            Console.WriteLine("Custom cultures:");
            foreach (var culture in custom)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();

        // Get all replacement cultures.
        CultureInfo[] replacements = CultureInfo.GetCultures(CultureTypes.ReplacementCultures);
        if (replacements.Length == 0)
        {
            Console.WriteLine("There are no replacement cultures.");
        }
        else
        {
            Console.WriteLine("Replacement cultures:");
            foreach (var culture in replacements)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();
    }
}
// The example displays output like the following:
//     Custom cultures:
//        x-en-US-sample -- English (United States)
//        fj-FJ -- Boumaa Fijian (Viti)
//
//     There are no replacement cultures.

Referencias culturales y subprocesos

Cuando se inicia un nuevo subproceso de aplicación, la referencia cultural actual y la referencia cultural de la interfaz de usuario actual se definen mediante la referencia cultural del sistema actual y no la referencia cultural del subproceso actual. En el siguiente ejemplo se ilustra la diferencia. Establece la referencia cultural actual y la referencia cultural de la interfaz de usuario actual de un subproceso de aplicación en la referencia cultural francesa (Francia) (fr-FR). Si la referencia cultural actual ya fuera fr-FR, el ejemplo lo establecerá en la referencia cultural inglesa (Estados Unidos) (en-US). Muestra tres números aleatorios como valores de moneda y, a continuación, crea un nuevo subproceso que, a su vez, muestra tres números aleatorios más como valores de moneda. Pero como se muestra en la salida del ejemplo, los valores de moneda mostrados por el nuevo subproceso no reflejan las convenciones de formato de la referencia cultural francesa (Francia), a diferencia de la salida de subproceso de la aplicación principal.

using System;
using System.Globalization;
using System.Threading;

public class DefaultThreadEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          8,11 €
//          1,48 €
//          8,99 €
//          9,04 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: en-US/en-US
//       Some currency values:
//          $6.72
//          $6.35
//          $2.90
//          $7.72

Es posible establecer la referencia cultural y la referencia cultural de la interfaz de usuario de todos los subprocesos de un dominio de aplicación asignando un objeto CultureInfo que represente esa referencia cultural de las propiedades DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture. En el ejemplo siguiente, se usan estas propiedades para asegurarse de que todos los subprocesos del dominio de aplicación predeterminado compartan la misma referencia cultural.

using System;
using System.Globalization;
using System.Threading;

public class SetThreadsEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(SetThreadsEx.ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          6,83 €
//          3,47 €
//          6,07 €
//          1,70 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          9,54 €
//          9,50 €
//          0,58 €
//          6,91 €

Advertencia

Aunque las propiedades DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture son miembros estáticos, definen la referencia cultural y la referencia cultural de interfaz de usuario predeterminadas solo para el dominio de aplicación que esté activo en el momento en que se establezcan estos valores de propiedad. Para obtener más información, consulte la sección siguiente, Referencias culturales y dominios de aplicación.

Al asignar valores a las propiedades DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture, la referencia cultural y la referencia cultural de la interfaz de usuario de los subprocesos del dominio de aplicación también cambiarán si no se les asignó explícitamente una referencia cultural. Sin embargo, estos subprocesos reflejan la nueva configuración de referencia cultural solo mientras se ejecutan en el dominio de aplicación actual. Si estos subprocesos se ejecutasen en otro dominio de aplicación, su referencia cultural se convertirá en la referencia cultural predeterminada definida para ese dominio de aplicación. Como resultado, se recomienda establecer siempre la referencia cultural del subproceso de aplicación principal y no confiar en las propiedades DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture para cambiarla.

Referencias culturales y dominios de aplicación

DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture son propiedades estáticas que definen explícitamente una referencia cultural predeterminada solo para el dominio de aplicación que sea el que haya cuando se establezca o recupere el valor de propiedad. En el ejemplo siguiente, se establece la referencia cultural y la referencia cultural de la interfaz de usuario predeterminadas del dominio de aplicación predeterminado en francés (Francia) y, a continuación, se usan la clase AppDomainSetup y el delegado AppDomainInitializer para establecer la referencia cultural y la referencia cultural de la interfaz de usuario predeterminadas en un nuevo dominio de aplicación en ruso (Rusia). A continuación, un único subproceso ejecuta dos métodos en cada dominio de aplicación. Tenga en cuenta que la referencia cultural y la referencia cultural de la interfaz de usuario del subproceso no se establecen explícitamente, sino que se derivan de la referencia cultural y la referencia cultural de la interfaz de usuario predeterminadas del dominio de aplicación en el que se ejecute el subproceso. Tenga en cuenta también que las propiedades DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture devuelven los valores predeterminados CultureInfo del dominio de aplicación que sea el que haya cuando se realice la llamada de método.

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
        // Set the default culture and display the current date in the current application domain.
        Info info1 = new Info();
        SetAppDomainCultures("fr-FR");

        // Create a second application domain.
        AppDomainSetup setup = new AppDomainSetup();
        setup.AppDomainInitializer = SetAppDomainCultures;
        setup.AppDomainInitializerArguments = new string[] { "ru-RU" };
        AppDomain domain = AppDomain.CreateDomain("Domain2", null, setup);
        // Create an Info object in the new application domain.
        Info info2 = (Info)domain.CreateInstanceAndUnwrap(typeof(Example).Assembly.FullName,
                                                           "Info");

        // Execute methods in the two application domains.
        info2.DisplayDate();
        info2.DisplayCultures();

        info1.DisplayDate();
        info1.DisplayCultures();
    }

    public static void SetAppDomainCultures(string[] names)
    {
        SetAppDomainCultures(names[0]);
    }

    public static void SetAppDomainCultures(string name)
    {
        try
        {
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture(name);
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture(name);
        }
        // If an exception occurs, we'll just fall back to the system default.
        catch (CultureNotFoundException)
        {
            return;
        }
        catch (ArgumentException)
        {
            return;
        }
    }
}

public class Info : MarshalByRefObject
{
    public void DisplayDate()
    {
        Console.WriteLine("Today is {0:D}", DateTime.Now);
    }

    public void DisplayCultures()
    {
        Console.WriteLine("Application domain is {0}", AppDomain.CurrentDomain.Id);
        Console.WriteLine("Default Culture: {0}", CultureInfo.DefaultThreadCurrentCulture);
        Console.WriteLine("Default UI Culture: {0}", CultureInfo.DefaultThreadCurrentUICulture);
    }
}
// The example displays the following output:
//       Today is 14 октября 2011 г.
//       Application domain is 2
//       Default Culture: ru-RU
//       Default UI Culture: ru-RU
//       Today is vendredi 14 octobre 2011
//       Application domain is 1
//       Default Culture: fr-FR
//       Default UI Culture: fr-FR

Para obtener más información sobre las referencias culturales y los dominios de aplicación, consulte la sección "Dominios de aplicación y subprocesos" del tema Dominios de aplicación.

Referencias culturales y operaciones asincrónicas basadas en tareas

El patrón de programación asincrónica basado en tareas usa los objetos Task y Task<TResult> para ejecutar de forma asincrónica delegados en subprocesos del grupo de subprocesos. El subproceso específico en el que se ejecuta una tarea determinada no se conoce de antemano, sino que solo se determina en tiempo de ejecución.

En el caso de las aplicaciones que tienen como destino .NET Framework 4.6 o una versión posterior, la referencia cultural forma parte del contexto de una operación asincrónica. Es decir, las operaciones asincrónicas heredan de forma predeterminada los valores de las propiedades CurrentCulture y CurrentUICulture del subproceso desde el que se inician. Si la referencia cultural actual o la referencia cultural de la interfaz de usuario actual difiriesen de la referencia cultural del sistema, la referencia cultural actual traspasará los límites de los subprocesos y se convertirá en la referencia cultural actual del subproceso del grupo de subprocesos que ejecute una operación asincrónica.

Esto se muestra en el ejemplo siguiente. En el ejemplo, se define un delegado Func<TResult>, formatDelegate, que devuelve algunos números con formato de valor de moneda. En el ejemplo, se cambia la referencia cultural actual del sistema al francés (Francia), o bien al inglés (Estados Unidos), en caso de que el francés (Francia) sea la referencia cultural actual. Entonces:

  • Invoca al delegado directamente para que se ejecute de forma sincrónica en el subproceso de la aplicación principal.
  • Crea una tarea que ejecuta el delegado de forma asincrónica en un subproceso de grupo de subprocesos.
  • Crea una tarea que ejecuta el delegado de forma sincrónica en el subproceso de la aplicación principal llamando al método Task.RunSynchronously.

Como se muestra en la salida del ejemplo, cuando la referencia cultural actual cambia a francés (Francia), la referencia cultural actual del subproceso desde la que las tareas se invocan de forma asincrónica se convierten en la referencia cultural actual para esa operación asincrónica.

using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;

public class AsyncCultureEx1
{
    public static void Main()
    {
        decimal[] values = { 163025412.32m, 18905365.59m };
        string formatString = "C2";

        string FormatDelegate()
        {
            string output = $"Formatting using the {CultureInfo.CurrentCulture.Name} " +
            "culture on thread {Thread.CurrentThread.ManagedThreadId}.\n";
            foreach (decimal value in values)
                output += $"{value.ToString(formatString)}   ";

            output += Environment.NewLine;
            return output;
        }

        Console.WriteLine($"The example is running on thread {Thread.CurrentThread.ManagedThreadId}");
        // Make the current culture different from the system culture.
        Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
        if (CultureInfo.CurrentCulture.Name == "fr-FR")
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        else
            Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");

        Console.WriteLine($"Changed the current culture to {CultureInfo.CurrentCulture.Name}.\n");

        // Execute the delegate synchronously.
        Console.WriteLine("Executing the delegate synchronously:");
        Console.WriteLine(FormatDelegate());

        // Call an async delegate to format the values using one format string.
        Console.WriteLine("Executing a task asynchronously:");
        var t1 = Task.Run(FormatDelegate);
        Console.WriteLine(t1.Result);

        Console.WriteLine("Executing a task synchronously:");
        var t2 = new Task<string>(FormatDelegate);
        t2.RunSynchronously();
        Console.WriteLine(t2.Result);
    }
}
// The example displays the following output:
//         The example is running on thread 1
//         The current culture is en-US
//         Changed the current culture to fr-FR.
//
//         Executing the delegate synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task asynchronously:
//         Formatting using the fr-FR culture on thread 3.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €

DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture son propiedades de dominio por aplicación, es decir, establecen una referencia cultural predeterminada para todos los subprocesos no asignados explícitamente a una referencia cultural en un dominio de aplicación específico. Sin embargo, para las aplicaciones que tengan como destino .NET Framework 4.6 o posterior, la referencia cultural del subproceso de llamada seguirá formando parte del contexto de una tarea asincrónica, incluso si la tarea cruzase los límites del dominio de la aplicación.

Serialización de objetos CultureInfo

Cuando se serializa un objeto CultureInfo, todo lo que realmente se almacena es Name y UseUserOverride. Se deserializa correctamente solo en un entorno donde Name tiene el mismo significado. Los tres ejemplos siguientes muestran por qué este no es siempre el caso:

  • Si el valor de propiedad CultureTypes fuera CultureTypes.InstalledWin32Cultures y si esa referencia cultural se introdujo por primera vez en una versión determinada del sistema operativo Windows, no será posible deserializarla en una versión anterior de Windows. Por ejemplo, si se introdujo una referencia cultural en Windows 10, no se podrá deserializar en Windows 8.

  • Si el valor de CultureTypes fuera CultureTypes.UserCustomCulture y el equipo en el que estuviera deserializado no tuviera instalada esta referencia cultural personalizada de usuario, no será posible deserializarlo.

  • Si el valor de CultureTypes fuera CultureTypes.ReplacementCultures y el equipo en el que estuviera deserializado no tuviera esta referencia cultural de reemplazo, se deserializará al mismo nombre, pero no todas las mismas características. Por ejemplo, si en-US fuera una referencia cultural de reemplazo en el equipo A, pero no en el equipo B, y si un objeto CultureInfo que hiciera referencia a esta referencia cultural se serializase en el equipo A y se deserializase en el equipo B, no se transmitirá ninguna de las características personalizadas de la referencia cultural. La referencia cultural deserializa correctamente, pero con un significado diferente.

Invalidaciones del Panel de control

El usuario podría querer invalidar algunos de los valores asociados a la referencia cultural de Windows actual a través de la sección de opciones regionales y de idioma de Panel de control. Por ejemplo, el usuario podría optar por mostrar la fecha en un formato diferente o usar una moneda distinta de la predeterminada para la referencia cultural. En general, las aplicaciones deberían respetar estas invalidaciones de usuario.

Si UseUserOverride fuera true y la referencia cultural especificada coincidiera con la referencia cultural actual de Windows, CultureInfo usará esas invalidaciones, incluyendo la configuración de usuario de para propiedades de la instancia DateTimeFormatInfo devuelta por la propiedad DateTimeFormat y las propiedades de la instancia NumberFormatInfo que devolvió propiedad NumberFormat. Si la configuración del usuario no fuera compatible con la referencia cultural asociada a CultureInfo (por ejemplo: si el calendario seleccionado fuera diferente de OptionalCalendars), los resultados de los métodos y los valores de las propiedades no estarán definidos.

Criterios de ordenación alternativos

Algunas referencias culturales admiten más de un criterio de ordenación. Por ejemplo:

  • La cultura española (España) tiene dos criterios de ordenación: el criterio de ordenación internacional predeterminado y el criterio de ordenación tradicional. Al crear una instancia de un objeto CultureInfo con el nombre de la referencia cultural es-ES, se usa el criterio de ordenación internacional. Al crear una instancia de un objeto CultureInfo con el nombre de la referencia cultural es-ES-tradnl, se usa el criterio de ordenación tradicional.

  • La referencia cultural zh-CN (chino (simplificado, RPC)), admite dos criterios de ordenación: por pronunciación (el predeterminado) y por número de trazos. Al crear una instancia de un objeto CultureInfo con el nombre de la referencia cultural zh-CN, se usa el criterio de ordenación predeterminado. Cuando se crea una instancia de un objeto CultureInfo con un identificador local 0x00020804, las cadenas se ordenarán por recuento de trazos.

En la tabla siguiente se enumeran las referencias culturales que admiten criterios de ordenación alternativos, y los identificadores para los criterios de ordenación predeterminados y alternativos.

Nombre de referencia cultural Referencia cultural Nombre e identificador de ordenación predeterminada Nombre e identificador de ordenación alternativa
es-ES Español (España) Internacional: 0x00000C0A Tradicional: 0x0000040A
zh-TW Chino (Taiwán) Número de trazos: 0x00000404 Bopomofo: 0x00030404
zh-CN Chino (RPC) Pronunciación: 0x00000804 Número de trazos: 0x00020804
zh-HK Chino (RAE de Hong Kong) Número de trazos: 0x00000c04 Número de trazos: 0x00020c04
zh-SG Chinese (Singapore) Pronunciación: 0x00001004 Número de trazos: 0x00021004
zh-MO Chinese (Macao SAR) Pronunciación: 0x00001404 Número de trazos: 0x00021404
ja-JP Japonés (Japón) Predeterminada: 0x00000411 Unicode: 0x00010411
ko-KR Coreano (Corea) Predeterminada: 0x00000412 Xwansung coreano - Unicode: 0x00010412
de-DE Alemán (Alemania) Diccionario: 0x00000407 Ordenación de libreta de teléfonos DIN: 0x00010407
hu-HU Húngaro (Hungría) Predeterminada: 0x0000040e Ordenación técnica: 0x0001040e
ka-GE Georgiano (Georgia) Tradicional: 0x00000437 Alfabetización internacional: 0x00010437

La referencia cultural actual y las aplicaciones para UWP

En las aplicaciones de Plataforma universal de Windows (UWP), las propiedades CurrentCulture y CurrentUICulture son de lectura y escritura, al igual que en las aplicaciones de .NET Framework y .NET Core. Sin embargo, las aplicaciones para UWP reconocen una única referencia cultural. Las propiedades CurrentCulture y CurrentUICulture se asignan al primer valor de la colección Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages.

En las aplicaciones de .NET, la referencia cultural actual es una configuración por subproceso, y las propiedades CurrentCulture y CurrentUICulture reflejan solo la referencia cultural y la referencia cultural de la interfaz de usuario del subproceso actual. En las aplicaciones para UWP, la referencia cultural actual se asigna a la colección Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages, que es una configuración global. Establecer la propiedad CurrentCulture o CurrentUICulture cambia la referencia cultural de toda la aplicación. La referencia cultural no se puede establecer por subproceso.