TOC

This article is currently in the process of being translated into Spanish (~99% done).

Working with Culture & Regions:

La clase CultureInfo

En el último par de artículos hemos hablado acerca de lo útil que es la clase CultureInfo cuando necesitas un control total de cómo se muestran los números y fechas en tu aplicación. También hemos hablado de cómo se puede verificar y modificar qué cultura debe usar su aplicación definida como instancia "CurrentCulture" o CulturaActual para todas las situaciones en que el usuario no indique que cultura debe usarse. Teniendo todo eso en cuenta, vamos a profundizar en la clase CultureInfo para ver cómo aprovecharla al máximo.

Recuerda que la clase CultureInfo es parte del espacio de nombres System.Globalization, por lo que asegúrate de importarlo cada vez que vayas a usarlo:

using System.Globalization;

Culturas neutras y específicas

En los ejemplos anteriores de este capítulo, solo hemos utilizado culturas específicas,es decir una cultura que especifica tanto un idioma como un país / región. Un ejemplo de esto es la cultura en-US, Que establece claramente que el idioma deseado debe ser el inglés y la región es EE. UU. Una alternativa a eso es la cultura en-GB, que es el mismo idioma (inglés) pero con Gran Bretaña como la región en lugar de los EE. UU.

Habrá ocasiones en que estas diferencias son importantes, en cuyo caso debe usar estas versiones específicas de la región de la clase CultureInfo. Por otro lado, también habrá situaciones en las que el inglés es solo un idioma y no desea vincular este idioma a un país o región específicos. Para esto, el framework .NET define las llamadas culturas neutras, que solo especifican un lenguaje. De hecho, tanto en-US como en-GB heredan de una cultura neutral (¡lo cual tiene mucho sentido, ya que comparten el mismo idioma!) y puede acceder a él desde la propiedad Parent. Veámoslo con un ejemplo:

CultureInfo enGb = new CultureInfo("en-GB");
CultureInfo enUs = new CultureInfo("en-US");
Console.WriteLine(enGb.DisplayName);
Console.WriteLine(enUs.DisplayName);
Console.WriteLine(enGb.Parent.DisplayName);
Console.WriteLine(enUs.Parent.DisplayName);

No es un ejemplo muy útil, pero debería darle una mejor idea de la estructura interna de la clase CultureInfo. La salida debería verse así:

English (United Kingdom)
English (United States)
English
English

Obteniendo la CultureInfo correcta

Con los ejemplos anteriores, ha visto que podemos obtener la clase CultureInfo deseada al pasar el identificador de idioma-país / región al constructor de la clase. Pero como podría estar buscando una cultura neutral, como se describió anteriormente, también podría pasar un identificador de idioma:

CultureInfo en = new CultureInfo("en");

El ambiente .NET entonces regresará una instancia CultureInfo Inglés-región neutra para usted. Para una lista completa de posibles identificadores de lenguaje y/o lenguaje-país/región, le sugiero revisar la MSDN documentación.

Otro modo de identificar una cultura específica es con el llamado LCID (LoCale ID). La encontrará como una propiedad en las instancias existentes de CultureInfo, pero si sabe el ID, puede también usarla para instanciar un objeto CultureInfo. Por ejemplo, el LCID para en-US es 1033:

CultureInfo enUs = new CultureInfo(1033);

Sin embargo, en la mayoría de las situaciones, es más fácil usar el especificador de lenguaje-país/región, como se demostró previamente.

Obteniendo una lista de Culturas disponibles

Ahora podemos obtener una cultura específica y usarla para nuestros propósitos, pero quizás usted necesite una lista de las culturas disponibles, por ejemplo, para permitirle al usuario seleccionar un lenguaje y/o un país/regón. Afortunadamente, el ambiente .NET lo hace fácil para todos nosotros también - aquí esta un ejemplo:

CultureInfo[] specificCultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);
foreach (CultureInfo ci in specificCultures)
    Console.WriteLine(ci.DisplayName);
Console.WriteLine("Total: " + specificCultures.Length);

Como puede ver de la primer línea de código, uso el método estático GetCultures en la clase CultureInfo para obtener una lista de culturas. Requiere el parámetro CultureTypes, el cual específica cual tipo de culturas usted esta buscando. En este caso, he buscado las culturas específicas, las cuales, como mencionamos previamente, son las culturas que tienen un lenguaje y un país/región. Esa es una lista bastante larga, de paso - en esta computadora, ¡Tengo un total de 563 culturas disponibles!

¿Pero quizá usted este más interesa en las culturas neutras? Eso haría, por ejemplo, sentido perfectamente si estuviera construyendo una lista de lenguajes disponibles, mientras no le importe a cuales países o regiones esten relacionados. Hacer esto es tan simple como cambiar el parámetro CultureTypes:

CultureInfo[] neutralCultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
foreach (CultureInfo ci in neutralCultures)
    Console.WriteLine(ci.DisplayName);
Console.WriteLine("Total: " + neutralCultures.Length);

Al hacerlo, también verá que no hay tantoas culturas neutras como culturas específicas - en mi computadora/versión del ambiente .NET, el resultado es un total de 280 culturas neutras.

Propiedades y métodos importantes de CultureInfo

Una vez que usted tenga una instancia de la clase CultureInfo, obtiene acceso inmediatemente a un rango muy amplio de propiedades y métodos usables. Estos miembros pueden ayudarle a lograr muchas cosas útiles respecto a la cultura - ¡Echémos un vistazo a algunas de estas!

DateTimeFormat

Con la propiedad DateTimeFormat, obtiene acceso a información acerca de como deberían ser formatedas la fecha y la hora, tanto como mucha información útil acerca del calendario para la cultura provista. Un buen ejemplo de esto son las propiedades FirstDayOfWeek y CalendarWeekRule - ellas pueden decirle en que día comienza una semana (usualmente Domingo o Lunes) y como se decide cual es la primera semana del calendario del año (por ejemplo, solamente el primer día o la primera semana completa):

CultureInfo enUs = new CultureInfo("en-US");
Console.WriteLine("First day of the: " + enUs.DateTimeFormat.FirstDayOfWeek.ToString());
Console.WriteLine("First calendar week starts with: " + enUs.DateTimeFormat.CalendarWeekRule.ToString());

Intente cambiar la instancia de CultureInfo a su propia cultura u otra cultura que conozca, para ver ¡Como varian estas propiedades!

Otra cosa genial es que puede obtener información acerca de los nombres del mes y el día para la cultura específica usando propiedades como MonthNames y métodos como GetMonthName(). Aqui está un ejemplo rápido:

CultureInfo enUs = new CultureInfo("en-US");

foreach (string monthName in enUs.DateTimeFormat.MonthNames)
    Console.WriteLine(monthName);
Console.WriteLine("Current month: " + enUs.DateTimeFormat.GetMonthName(DateTime.Now.Month));

Y la misma cosa puede ser lograda para días, usando la propiedad DayNames y el método GetDayName():

CultureInfo enUs = new CultureInfo("en-US");

foreach (string dayName in enUs.DateTimeFormat.DayNames)
    Console.WriteLine(dayName);
Console.WriteLine("Today is: " + enUs.DateTimeFormat.GetDayName(DateTime.Now.DayOfWeek));

Hay muchas más propiedades y métodos útiles en la propiedad DateTimeFormat, por ejemplo, DateSeparator, YearMonthPattern y otros. Éche un vistazo por si mismo - quizá hay una solución para su problema relacionado con fechas/hora oculta allí: documentación DateTimeFormatInfo.

NumberFormat

Así como DateTimeFormat tienen información acerca de fechas, usted puede accesar información sobre como la cultura específica trata a los números desde la propiedad NumberFormat. Esta información es usada cada vez que usted busca una representación visual de un número, por ejemplo, cuando lo convierte a una cadena o lo escribe en la consola, pero también puede accesar información usted mismo, usando las propiedades y métodos en la propiedad NumberFormat - aquí está un ejemplo:

CultureInfo enUs = new CultureInfo("en-US");  
Console.WriteLine(enUs.DisplayName + ":");  
Console.WriteLine("NumberGroupSeparator: " + enUs.NumberFormat.NumberGroupSeparator);  
Console.WriteLine("NumberDecimalSeparator: " + enUs.NumberFormat.NumberDecimalSeparator);  

CultureInfo deDe = new CultureInfo("de-DE");  
Console.WriteLine(deDe.DisplayName + ":");  
Console.WriteLine("NumberGroupSeparator: " + deDe.NumberFormat.NumberGroupSeparator);  
Console.WriteLine("NumberDecimalSeparator: " + deDe.NumberFormat.NumberDecimalSeparator);

Usamos las propiedades NumberGroupSeparator y NumberDecimalSeparator para obtener información acerca de como un número es desplegado (por ejemplo 1,000.00 o 1.000,00) para las culturas Inglésa y Alemana. Si le écha una vista, encontrará propiedades que empatan para monedas (CurrencyGroupSeparator y CurrencyDecimalSeparator) también como porcentajes (PercentGroupSeparator y PercentDecimalSeparator).

Hablando de monedas, la propiedad NumberFormat también puede decirnos que símbolo usa una cultura dada para desplegar una cantidad monetaria - simplemente use la propiedad CurrencySymbol:

CultureInfo enUs = new CultureInfo("en-US");
Console.WriteLine(enUs.DisplayName + " - currency symbol: " + enUs.NumberFormat.CurrencySymbol);
CultureInfo deDe = new CultureInfo("de-DE");
Console.WriteLine(deDe.DisplayName + " - currency symbol: " + deDe.NumberFormat.CurrencySymbol);
CultureInfo ruRu = new CultureInfo("ru-RU");
Console.WriteLine(ruRu.DisplayName + " - currency symbol: " + ruRu.NumberFormat.CurrencySymbol);

Es chévere conocer acerca de todas estas propiedades, pero en la mayoria de situaciones, no tendrá que lidiar con ellas, ya que C# usará silenciosamente la información para formatear números, porcentajes y monedas por usted, tan pronto como usted especifique la cadena de formato cuando convierta un número en cadena.

Números e identificadores

Por último, veamos las propiedades que representan a la instancia CultureInfo. Ya hemos usado algunas de ellas, por ejemplo Name y DisplayName, pero ¿Cómo trabajan en realidad? Primero, aquí está una lista de propiedades disponibles usadas para identificar una CultureInfo:

  • Name identificará una CultureInfo en el formato código lenguaje-código país/región, por ejemplo "en-US" para Inglés en los Estados Unidos, en-GB para Inglés en Gran Bretaña y así. Si no se especifica país/región, solamente la primer parte será regresada, por ejemplo "en" para Inglés.
  • TwoLetterISOLanguageName hará casí lo mismo que Name, pero solamente retornará el código del lenguaje, no importa si un país/región ha sido especificado o no. Por ejemplo, "en" será retornado para ambos "en-US" y "en-GB". Las letras retornadas son especificadas en el estándar ISO 639-1.
  • ThreeLetterISOLanguageName trabaja muy parecido a TwoLetterISOLanguageName, pero retorna tres letras en lugar de dos, somo se especifica por el estándar ISO 639-2.
  • EnglishName retornará el nombre del lenguaje (en Inglés). Si un país/región ha sido especificado, este será agregado al resultado, dentro del conjunto de paréntesis.
  • NativeName retornará el nombre del lenguaje (en el lenguaje especificado en la instancia CultureInfo). Si un país/región ha sido especificado, este será agregado al resultado, dentro del conjunto de paréntesis.

Resumen

Como puede recabar de lo extenso de este artículo, lidiar con culturas en general no es una tarea simple. Afortunadamente para nosotros, el ambiente .NET lo hace mucho más sencillo con la clase CultureInfo. Es usada silenciosamente através de su aplicación cuando se formatean números y fechas, pero es bueno que usted conozco como trabaja y así pueda modificar el comportamiento si lo necesita. Ojalá este artículo le haya enseñado la mayoría de lo que necesita saber acerca de la clase CultureInfo.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!