CultureInfo. Personalizar formatos

Recientemente publiqué un post en el que había creado una clase que facilitaba la labor de crear ficheros delimitados. Como suele ocurrir casi siempre, baso los artículos en vivencias de mi vida laboral. Es por esto que, tal como ha sucedido en el presente, en más de una ocasión, tras resolver un problema, surge otro nuevo.

El caso es que, hasta el momento, cuando había tenido que crear un fichero de este tipo para enviar al exterior, siempre estaba hablando con empresas españolas. En este caso, es distinto, puesto que el fichero irá a parar a una multinacional que, lógicamente, impone sus normas. En principio, estas normas no suelen dar muchos problemas, pero sí que representan algún trastorno en lo referente a los formatos numéricos y de fechas.

Reconozco que hasta el momento nunca me había preocupado mucho de estos temas de crear aplicaciones multilingües ni tal siquiera de cambiar determinados formatos, sobre todo numéricos, pero como ha llegado el momento de hacerlo, pues he empezado a interesarme, de momento, por alguna herramienta que nos ofrece el Framework. En esta ocasión no he pasado de la clase CultureInfo, aunque no descarto seguir con las interfaces IFormatProvider e ICustomFormater, que me han dado muy buenas vibraciones.

Bueno, vamos al grano, que siempre me disipo intentando entrar en situación. El caso es que necesito tener un modo más o menos centralizado en el que pueda definir cómo quedarán los formatos de fecha y numéricos, así que lo mejor que he sabido ver es crear una clase CulturaPropia, en la que pueda personalizar los formatos que necesito. Esta clase heredará de otra del Framework, la clase CultureInfo.

using System;
using System.Globalization;

namespace JnSoftware.Samples
{
    class CulturaPropia : CultureInfo
    {
        public CulturaPropia()
            : base("es-ES")
        {
            setFormatoNumerico();
            setFormatoMoneda();
            setFormatoFecha();
        }

        /// <summary>
        /// Establece formatos numéricos
        /// </summary>
        private void setFormatoNumerico()
        {
            NumberFormatInfo n = this.NumberFormat;
            n.NumberNegativePattern = 0;
            n.NumberGroupSeparator = ",";
            n.NumberDecimalSeparator = ".";
        }

        /// <summary>
        /// Establece formatos de Moneda
        /// </summary>
        private void setFormatoMoneda()
        {
            NumberFormatInfo n = this.NumberFormat;
            n.CurrencyPositivePattern = 3;
            n.CurrencySymbol = "EUR";
        }

        /// <summary>
        /// Establece formatos de fecha
        /// </summary>
        private void setFormatoFecha()
        {
            DateTimeFormatInfo d = this.DateTimeFormat;
            d.LongDatePattern = "'Montcada i Reixac, 'dd' de 'MMMM' de 'yyyy" ;
            d.ShortDatePattern = "dd.MMM.yyyy";
            d.FirstDayOfWeek = DayOfWeek.Monday;
            d.TimeSeparator = "/";
            d.DateSeparator = ".";
        }
    }
}

Como se puede apreciar, la clase es bien sencilla, puesto que, desde el mismo constructor, lo que intenta es “heredar” toda la información de una referencia cultural completa (en el ejemplo es-ES, correspondiente a España). A partir de aquí, tan sólo es cuestión de ir modificando aquellas propiedades de la clase que necesitemos.

Para la ejecución de las pruebas, he creado un proyecto de consola en el cual, sencillamente, muestro una comparación entre tres referencias diferentes: americana, española y la que he creado. Es posible que existan otras opciones de hacerlo, pero he visto que me resulta muy cómodo cambiar la referencia cultural al Thread actual, extraer los datos y volver a dejar tal cuál estaba la referencia.

using System;
using System.Globalization;

namespace JnSoftware.Samples
{
    class EjecucionPruebas
    {
        // Muestra diversa información en pantalla.
        public void MuestraEjemplo(string titulo, CultureInfo cultura)
        {
            DateTime fecha = DateTime.Now;
            double numero = 12345.6789;

            System.Threading.Thread.CurrentThread.CurrentCulture = cultura;
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(new string('=', Console.WindowWidth - 1));
            Console.WriteLine(titulo);
            Console.WriteLine(new string('=', Console.WindowWidth - 1));
            Console.ResetColor();
            Console.WriteLine("Fecha 1  : t{0:d}", fecha);
            Console.WriteLine("Fecha 2  : t{0:D}", fecha);
            Console.WriteLine("General  : t{0:G}", numero);
            Console.WriteLine("Moneda   : t{0:C}", numero);
            Console.WriteLine("Decimal  : t{0:D}", (int)numero);
            Console.WriteLine("Número   : t{0:N}", numero);
            Console.WriteLine("P. Fijo  : t{0:F}", numero);
        }

        // Ejecución de las pruebas.
        public static void Main()
        {
            // Lectura de la referencia actual
            CultureInfo actual = System.Threading.Thread.CurrentThread.CurrentCulture;
            Console.WindowHeight = 31;
            EjecucionPruebas test = new EjecucionPruebas();
            // Cambios de referencia culturales 
            test.MuestraEjemplo("en-US", new CultureInfo("en-US"));
            test.MuestraEjemplo("es-ES", new CultureInfo("es-ES"));
            test.MuestraEjemplo("Propia", new CulturaPropia());
            test = null;
            // Se establece la referencia inicial
            System.Threading.Thread.CurrentThread.CurrentCulture = actual;
            Console.ReadKey();
        }
    }
}

Tal como puede apreciarse, salvo algún ornamento añadido para que se muestre mejor la pantalla resultante, lo único que se hace en la aplicación es mostrar los mismos datos en las diferentes referencias culturales.

El resultado será el siguiente:

image

2 thoughts on “CultureInfo. Personalizar formatos

  1. Hola Jesús,

    muy buenas entradas las dos que has publicado recientemente sober delimitación de ficheros y este de CultureInfo.

    A veces es bueno enseñar a otras personas lo que hacemos y como lo hacemos. Felicidades por ello.

    Un saludo,

    Jorge

Responder a jvelasco Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *