domingo, 5 de octubre de 2008

Relative dates - Outlook style

Me gusta esa característica que tienen algunas aplicaciones de proporcionarnos búsquedas en base a fechas relativas, como lo hace Outlook o IE. Y es que siempre es más fácil ver tus archivos categorizados en el tiempo con fechas relativas que con la fecha exacta.

Esto es más agradable a la vista...

  • X hours ago
  • X days ago
  • more than a week ago
  • more than a  Month ago
  • about a Year ago

que esto...

  • 28 - septiembre - 2008
  • 27- septiembre - 2008
  • 3 - septiembre - 2008
  • 25 - agosto - 2008
  • 25 - agosto - 2008
  • 25 - agosto - 2008
  • 25 - agosto - 2007

Y así sucesivamente. Moraleja tener nuestros archivos ordenados por fechas relativas es bueno para nuestra vida ñ_ñ

Y aquí les dejo un pequeño algoritmo que toma una fecha y determina su antigüedad catalogándolo como fechas relativa. Si bien esto no es muy complejo quizá lo primero que se viene a la mente son una cantidad muy grande de sentencias if, else...cosa que nunca es agradable leer y escribir en un código. Aquí les dejo una sugerencia de lo que podría ser esto usando las bondades de C# 3.0...y aparte lo voy a hacer con un extension method ñ_ñ.

La clase del Extension Method luce así

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace RelativeDates

{

    public static class DateExtensions

    {

        public static String ToRelativeDate(this DateTime inputDate)

        {

            TimeSpan timeDiff = DateTime.Now.Subtract(inputDate);

            double totalMinutes = timeDiff.TotalMinutes;

            string timeIndicator = "ago";

 

            //El valor será un diccionario y se usa el tipo anónimo

            //"var" para no repetir la sintaxis de la incialización

            var value = new Dictionary<double, Func<string>>();

            value.Add(1440,()=>String.Format("about {0} hours ",Math.Round(Math.Abs(timeDiff.TotalHours))));

            value.Add(10080, () => String.Format("about {0} days ",Math.Round(Math.Abs(timeDiff.TotalDays))));

            value.Add(40320, () => String.Format("about {0} weeks ", Math.Round(Math.Abs(timeDiff.TotalDays / 7))));

            value.Add(483840,()=> String.Format("about {0} months ", Math.Round(Math.Abs(timeDiff.TotalDays / 30))));

            value.Add(int.MaxValue, () => "more than a Year ");

            return value.First(n=> totalMinutes < n.Key).Value.Invoke() + timeIndicator;

        }

    }

}

 

 

Y la podemos usar así:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace RelativeDates

{

    class Program

    {

        static void Main(string[] args)

        {

            DateTime relativeTime = new DateTime(2008,4,12);

            Console.WriteLine(relativeTime.ToString());

            Console.WriteLine(relativeTime.ToRelativeDate());

            Console.Read();

        }

    }

}

Espero les sirva, cualquier duda o comentario aquí lo discutimos.

Saludos

No hay comentarios.: