Internacionalizar las fechas (o parte de ellas)

Nunca dejará de sorprenderme la librería de clases del .Net Framework. Ahora que andamos liados con el tema de internacionalización de un par de aplicaciones se nos presentaba la problemática de tener que mostrar, en algún momento, algún que otro control en el que se tiene que, por ejemplo, rellenar un combo con los meses del año en el idioma del usuario. Comúnmente, cuando he hecho esto con anterioridad siempre me he creado algún que otro método en la capa de negocios que devolviese los meses, los meses abreviados, los días…

Si hablamos de aplicaciones en los que sólo interviene un idioma recuerdo haber creado casi siempre un método que devuelva los meses del año. Algo así como:

   1: public string[] GetMeses1()
   2:       {
   3:           string[] meses = 
   4:           {
   5:               "Enero", "Febrero", "Marzo",
   6:               "Abril", "Mayo", "Junio",
   7:               "Julio", "Agosto", "Septiembre",
   8:               "Octubre", "Noviembre", "Diciembre"
   9:           };
  10:           return meses;
  11:       }

Realmente es sencillo el método y, quizás por eso, muchos desarrolladores prefieren escribir algún algoritmo para evitar teclear todos y cada uno de los meses del año, así que éste podría ser un buen sustituto

   1: public string[] GetMeses2()
   2: {
   3:     string[] meses = new string[12];
   4:  
   5:     // Se obtiene un día cualquiera del primer mes de cualquier año
   6:     DateTime primerMes = new DateTime(1900, 1, 1);
   7:     for (int i = 0; i < 12; i++)
   8:     {
   9:         // Se suman los meses a la fecha inicial
  10:         meses[i] = primerMes.AddMonths(i).ToString("MMMM");
  11:     }
  12:     return meses;
  13: }

Hasta ahora esto ha sido lo sencillo y lo que en más de una ocasión hemos usado todos. La entrada de aplicaciones con necesidades de internacionalización nos haría pensar, si aun estamos usando el primero de los métodos en algún tipo de estructura if o switch o algo del siguiente estilo:

   1: public string[] GetMeses3(System.Globalization.CultureInfo culture)
   2: {
   3:     string[] meses = new string[12];
   4:  
   5:     // Se obtiene un día cualquiera del primer mes de cualquier año
   6:     DateTime primerMes = new DateTime(1900, 1, 1);
   7:     for (int i = 0; i < 12; i++)
   8:     {
   9:         // Se suman los meses a la fecha inicial
  10:         meses[i] = primerMes.AddMonths(i).ToString("MMMM",culture);
  11:     }
  12:     return meses;
  13: }

Como solución rápida no está mal del todo, no obstante debemos tener en cuenta que, además de los meses, en las aplicaciones acabamos usando listas con, por ejemplo, los días de la semana. ¿Qué hacemos ahora?. ¿Creamos un método que nos busque un lunes y calcule hasta el domingo? ¿Qué pasa con los lugares en los que el primer día de la semana es el domingo en vez de el lunes?. El caso es que buscando algún tipo de respuesta a estas preguntas me he encontrado con una propiedad de la clase CultureInfo realmente interesante, concretamente la propiedad DateTimeFormat que nos devuelve una instancia de la clase DateTimeFormatInfo, la cual contiene propiedades muy interesante que nos facilitarán enormemente el trabajo. Un ejemplo de esto puede ser un método que nos devuelva la misma información que cualquiera de los métodos mostrados con anterioridad:

   1: public string[] GetMeses4(System.Globalization.CultureInfo culture)
   2: {
   3:     return culture.DateTimeFormat.MonthNames;
   4: }

No obstante, la clase DateTimeFormatInfo nos ofrece una serie de métodos y propiedades que nos puede ser muy útil cada vez que necesitemos echar mano de, por ejemplo:

  • DayNames, que obtiene los nombres de los días de la semana.
  • ShortestDayNames, que obtiene una matriz con los nombres abreviados de la semana.
  • GetDayName. Método que nos permite obtener el nombre de un día determinado
  • GetMonthName. Ídem con el nombre de un mes concreto.