sábado, 16 de julio de 2016

Formato y Parseo en C# - Parte 2/2: Parseo y Proveedores de Formato

Índice

1. Introducción
2. Palabras Clave
3. Proveedores de Formato
4. Uso de NumberFormatInfo y DateTimeFormatInfo
4.1 Clase NumberFormatInfo
4.2 Clase DateTimeFormatInfo
5. Formato Compuesto
6. Parseo con Proveedores de Formato
7. Interfaces IFormatProvider y ICustomFormatter
8. Conclusiones
9. Literatura & Enlaces

1. Introducción

Esta segunda parte de la serie Formato y Parseo en C# explica los conceptos fundamentales acerca de proveedores de formato; entre ellos: NumberFormatInfo, DateTimeFormatInfo y CultureInfo. Se muestran ejemplos prácticos acerca de uso para afianzar su comprensión y reconocer los escenarios donde resultan de invaluable utilidad estas clases.

2. Palabras Clave

  • Cultura invariable
  • CultureInfo
  • DateTimeFormatInfo
  • Formato
  • Formato compuesto
  • NumberFormatInfo
  • Parseo

3. Proveedores de Formato

En lo que se refiere a proveedores de formato, en .NET Framework se cuenta en principio con dos proveedores: NumberFormatInfo y DateTimeFormatInfo; estos dos constituyen un mecanismo indirecto de deducción de CultureInfo.

El propósito de NumberFormatInfo y DateTimeFormatInfo, en este contexto, es determinar las configuraciones regionales culturales de formato.

Se puede poner como ejemplo la especificación de una cultura específica como la británica: 

System.Globalization.CultureInfo ru =
System.Globalization.CultureInfo.GetCultureInfo("en-GB");
Console.WriteLine(5.ToString("C", ru));

La invocación a ToString con "C" especifica las instrucciones para el formato: moneda; mientras que proveedor de formato para cultura británica -"en-GB"- lleva a cabo la traducción de las instrucciones al formato que corresponde: 

£5.00

Es importante mencionar que este código, de forma implícita, aplica el proveedor de formato predeterminado para valores numéricos NumberFormatInfo.

Para el caso de fechas, este ejemplo ilustra cómo formatear un objeto DateTime con cultura invariable. El hecho de establecer una cultura invariable significa que el formato es independiente de la configuración del sistema: 

DateTime dt = new DateTime(2013, 1, 2);
System.Globalization.CultureInfo ci =
System.Globalization.CultureInfo.InvariantCulture;

Console.WriteLine(dt.ToString(ci));
Console.WriteLine(dt.ToString("d", ci));

Esto produce como resultado 

01/02/2013 00:00:00
01/02/2013

La cultura invariable está basada en Estados Unidos. Entre las diferencias sobresalientes resaltan (Albahari, 2012)
  • El símbolo de moneda es  en lugar de $.
  • Horas y fechas se formatean con ceros a la izquierda.
  • El formato de hora está basado en hora 24 horas.

4. Uso de NumberFormatInfo y DateTimeFormatInfo

4.1 Clase NumberFormatInfo

La clase NumberFormatInfo provee funcionalidad para formatear y parsear valores numéricos ("NumberFormatInfo Class", 2016).

El siguiente ejemplo cambia el separador de miles: 

NumberFormatInfo nfi = new NumberFormatInfo();
nfi.NumberGroupSeparator = " ";

Console.WriteLine(98765.4321.ToString("N3", nfi));

La configuración predeterminada para esta clase está basada en la cultura invariante.

4.2 Clase DateTimeFormatInfo

De forma análoga a NumberFormatInfo, la clase DateTimeFormatInfo permite especificar el formato para fechas de acuerdo a una cultura específica ("DateTimeFormatInfo Class", 2016).

DateTimeFormatInfo dtfi = new DateTimeFormatInfo();
dtfi.DateSeparator = "-";
DateTime dt = DateTime.Now;

Console.WriteLine(dt.ToString("d", dtfi));

Luego el formato de la fecha después de ejecutar estas líneas de código es: 

07-16-2016

5. Formato Compuesto

Un formato compuesto permite al programador combinar un marcador de posición o placeholder con una cadena de formato. Para lograr esto, la clase String provee el método Format que recibe un objeto string -la cadena que representa el formato compuesto- y el arreglo de argumentos para los marcadores de posición o placeholders.

Este es un ejemplo básico de uso 

string formatoCompuesto = "Total = {0:C}";
Console.WriteLine(String.Format(formatoCompuesto, 1500000));

que produce como resultado 

Total = $1,500,000.00

6. Parseo con Proveedores de Formato

En .NET no se cuenta con una interfaz estándar para parsear (convertir) una cadena a través de un proveedor de formato (Albahari, 2012). Por lo tanto se requiere que cada tipo sobrecargue las versiones de los métodos static Parse y TryParse para aceptar como argumentos un proveedor de formato, y de forma opcional, un valor de las enumeraciones NumberStyles ("NumberStyles Enumeration", 2016) y DateTimeStyles ("DateTimeStyles Enumeration", 2016) para controlar cómo debe llevarse a cabo la conversión.

El código fuente C# que viene a continuación remueve paréntesis del valor original pasado al método Parse

int dosNegativo = int.Parse("(2)", NumberStyles.Integer
| NumberStyles.AllowParentheses);

Console.WriteLine(dosNegativo);

Resultado presentando en la salida estándar: 

-2

7. Interfaces IFormatProvider y ICustomFormatter

Los proveedores de formato visto hasta este punto implementan las interfaces IFormatProvider ("IFormatProvider Interface", 2016) y ICustomFormatter ("ICustomFormatter Interface", 2016).

El propósito común de este par de interfaz es proveer un mecanismo de indirección: es decir, permitir que un objeto CultureInfo determine cuál de los dos objetos NumberFormatInfo o DateTimeFormatInfo lleve a cabo la tarea de formato (Albahari, 2012).

8. Conclusiones

Se estudiaron los proveedores de formato que permiten establecer cómo se debe formatear un valor de un tipo de dato específico -por ejemplo un valor numérico o una fecha-. También se estudió cómo usar el formato compuesto para la combinación de una cadena de formato y un placeholder. Al final se describió, en breve, dos interfaces que implementan los proveedores de formato: IFormatProvider y ICustomFormatter.

En los siguientes artículos se estudia las cadenas de formato estándar junto con las banderas de parseo.

9. Literatura & Enlaces

Albahari, J., Albahari, B. (2012). C# 5.0 in a Nutshell. United States: O'Reilly Media.
NumberFormatInfo Class (System.Globalization) (2016, julio 16). Recuperado desde: https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo(v=vs.110).aspx
DateTimeFormatInfo Class (System.Globalization) (2016, julio 16). Recuperado desde: https://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo(v=vs.110).aspx
NumberStyles Enumeration (System.Globalization) (2016, julio 16). Recuperado desde: https://msdn.microsoft.com/en-us/library/System.Globalization.NumberStyles.aspx
DateTimeStyles Enumeration (System.Globalization) (2016, julio 16). Recuperado desde: https://msdn.microsoft.com/en-us/library/91hfhz89.aspx
IFormatProvider Interface (System) (2016, julio 16). Recuperado desde: https://msdn.microsoft.com/en-us/library/System.IFormatProvider.aspx
ICustomProvider Interface (Microsoft.ApplicationServer.Caching) (2016, julio 16). Recuperado desde: https://msdn.microsoft.com/en-us/library/microsoft.applicationserver.caching.icustomprovider(v=azure.10).aspx


O

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.