domingo, 18 de abril de 2010

C# – Descripción del Mes

 

Introducción

En esta ocasión se describirá las distintas técnicas que pueden aplicarse para obtener la descripción del mes.

Muchas veces sucede que dado una fecha, es necesario mostrar al usuario que mes se ha esta seleccionado, pero no alcanza con mostrar el numero que lo representa, sino que es necesario visualizar la descripción del mismo, y en el idioma del usuario.

Existen varias técnicas y formas de lograrlo, en este articulo se intentara abordad las alternativas que utilizo.

Obtener mes en una cultura especifica, usando método de extensión

El ejemplo de este punto se podrá visualizar en el código del Form1.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {
        textBox1.Text = dateTimePicker1.Value.Month.MonthName().CapitalizeFirstLetter();
    }


}

public static class DateTimeHelper
{

    public static string MonthName(this int month)
    {
        DateTimeFormatInfo dtinfo = new CultureInfo("es-ES", false).DateTimeFormat;
        return dtinfo.GetMonthName(month);
    }

    public static string CapitalizeFirstLetter(this string value)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value);
    }
}

En el código se puede observar la declaración de una clase estática, la cual contiene dos métodos:

- MonthName(), define un parámetro del tipo entero el cual representa el numero del mes, del cual se quiere obtener la descripción.

- CapitalizeFirstLetter(), en realidad este es solo un agregado, el cual hará que la descripción del mes tenga la primer letra en mayúsculas. Si la cultura usada es Ingles, esta de por si ya trae la primer letra en mayúscula, pero para idiomas Español, no es así, por eso hay que agrégasela.

En el evento ValueChange del DateTimePicker, se toma la fecha seleccionada y se recupera solo el mes en formato numéricos pero al definir un método de extensión para los enteros al inspeccionar los métodos habilitados estará el que hemos creado, lo interesante por remarcar es que los métodos de extensión permiten invocarlos directamente sin tener que pasar un valor por parámetro.

El único inconveniente de esta implementación es que la cultura, (o se el idioma) en el cual se recupera la descripción del mes, esta fija en el método.

Obtener mes en una cultura especifica, usando método simple

En el Form2 se podrá ver la misma implementación del punto anterior, pero en esta oportunidad se hace uso de método simples.

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {
        textBox1.Text = CapitalizeFirstLetter(MonthName(dateTimePicker1.Value.Month));
    }


    public string MonthName(int month)
    {
        DateTimeFormatInfo dtinfo = new CultureInfo("es-ES", false).DateTimeFormat;
        return dtinfo.GetMonthName(month);
    }

    public string CapitalizeFirstLetter(string value)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value);
    }

}

En este caso cada método recibe por parámetro el valor que necesita para poder trabajar.

Obtener mes seleccionando la cultura y usando método de extensión

En esta otra implementación iremos un poco mas allá, al permitir que el idioma del mes se obtenga en base a la cultura seleccionada, o la que este definida en la aplicación.

El ejemplo se dividió en dos formulario: Form3 y Form4, ya que era preciso que en la inicialización se pudiera cambiar el Thread.CurrentThread.CurrentCulture, lo cual no se podía lograr si estamos situados en el mismo form.

public partial class Form4 : Form
{
    public Form4()
    {
        InitializeComponent();
    }

    public Form4(CultureInfo culture) : this()
    {
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;
    }

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {
        textBox1.Text = MonthNameCurrentCulture(dateTimePicker1.Value.Month);
        
    }


    public string MonthNameCurrentCulture(int month)
    {
        DateTimeFormatInfo dtinfo = Thread.CurrentThread.CurrentCulture.DateTimeFormat;
        return dtinfo.GetMonthName(month);
    }
}

En el Form4 se recibe la cultura por parámetro, ya que es preciso que sea en la inicialización del form donde se especifique, es por ello que se ha creado un constructor nuevo en el Form4.

Lo destacable es que ahora el método MonthNameCurrentCulture() usa la cultura de la aplicación para obtener la descripción del mes, ya no esta fija como en los ejemplos anteriores.

Obtener mes mediante el formato de la fecha

Una otra alternativa valida, se podría usar el formato que se puede aplicar a un tipo DateTime, cuando se lo convierte a string.

En el Form6 justamente se hace uso de esta técnica, aplicando el formato MMMM, el cual devuelve la descripción del mes, para la fecha seleccionada.

public partial class Form5 : Form
{
    public Form5()
    {
        InitializeComponent();
    }

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {
        if(rbespanol.Checked)
            textBox1.Text = dateTimePicker1.Value.ToString("MMMM", CultureInfo.CreateSpecificCulture("es-ES")); 
        else if(rbingles.Checked)
            textBox1.Text = dateTimePicker1.Value.ToString("MMMM", CultureInfo.CreateSpecificCulture("en-US")); 
    }

}

Aclaraciones generales

Hay que recordar el agregado del using de System.Globalization, para que reconozca los métodos.

 

[C#]
[VB.NET]

3 comentarios:

  1. Muchas gracias por tu aporte excelente blog

    ResponderEliminar
  2. como puedo definirlo para todo el proyecto de una manera de una manera global

    ResponderEliminar
  3. hola Heyner

    imagino quieres definir lo metodo para usarlos desde distintos formularios

    pero alli esta definido de esta forma cuando se usa

    public static class DateTimeHelper

    solo que podrias ponerlo en un archivo .cs separado

    saludos

    ResponderEliminar