jueves, 30 de septiembre de 2010

C# Diferencia de Fechas en Años, Meses y Días

En C# solo contamos con un método que nos regresa la cantidad de días entre dos fechas que seria como sigue:

DateTime oldDate = "2 de Enero de 1989";
DateTime newDate = "3 de Febrero de 1990";
TimeSpan ts = newDate - oldDate;
String Dias = ts.Days.ToString();

Pero lo que realmente queremos es saber cuantos años, meses y días hay.
Lo que utilice fue el siguiente método que le envió ambas fechas y me regresa un String con el dato.

private String DiferenciaFechas(DateTime newdt, DateTime olddt)
{
Int32 anios;
Int32 meses;
Int32 dias;
String str = "";

anios = (newdt.Year - olddt.Year);
meses = (newdt.Month - olddt.Month);
dias = (newdt.Day - olddt.Day);

if (meses < 0)
{
anios -= 1;
meses += 12;
}
if (dias < 0)
{
meses -= 1;
dias += DateTime.DaysInMonth(newdt.Year, newdt.Month);
}

if (anios < 0)
{
return "Fecha Invalida";
}
if (anios > 0)
str = str + anios.ToString() + " años ";
if (meses > 0)
str = str + meses.ToString() + " meses ";
if (dias > 0)
str = str + dias.ToString() + " dias ";

return str;
}

14 comentarios:

  1. Gracias, efectivamente ése es el método.

    Saludos

    ResponderEliminar
  2. calcula mal, tiene problemas con los bisiestos.

    ResponderEliminar
  3. he vuelto a mirar el código y hacer nuevas pruebas. Me retracto de mi comentario anterior. No puedo decir que este mal. Todo depende de con que criterio calcules.

    ResponderEliminar
  4. Muchas gracias por compartir el código, no iba por tan mal camino pero me ayudaste mucho en verdad, :)

    ResponderEliminar
  5. Amigo soy re-novato en c#. El primer código que pones lo pegue en un botón. Y el segundo lo puse por aparte del botón.. Imprimo la variable "dias" en un Messagebox y solo me imprime la cantidad de días entre esas 2 fechas. Pero quiero que me muestre los meses y años, he intentado imprimir la variable anios y meses y no me deja. La verdad si me pudieras colaborar te agradeceria.

    ResponderEliminar
    Respuestas
    1. lo que tenes que copiar y pegar es el metodo DiferenciaFechas
      captura en pantalla la fecha newdt y olddt y se las envias como parametros
      lo que te regrese ese metodo lo envias al Messagebox y te deberia dar el total en años, meses y dias.

      Si no copia y pega aca el codigo que estas colocando para darme una mejor idea.

      Por cierto.. Gracias por comentar a todos los que lo han hecho.

      Eliminar
    2. Muy buena función!
      Aca va una versión mejorada en cuanto a los textos:

      private String DiferenciaFechas(DateTime newdt, DateTime olddt)
      {
      Int32 anios;
      Int32 meses;
      Int32 dias;
      String str = "";

      anios = (newdt.Year - olddt.Year);
      meses = (newdt.Month - olddt.Month);
      dias = (newdt.Day - olddt.Day);

      if (meses < 0)
      {
      anios -= 1;
      meses += 12;
      }
      if (dias < 0)
      {
      meses -= 1;
      dias += DateTime.DaysInMonth(newdt.Year, newdt.Month);
      }

      if (anios < 0)
      {
      return "La fecha inicial es mayor a la fecha final";
      }
      if (anios > 0)
      {
      if (anios == 1)
      str = str + anios.ToString() + " año ";
      else
      str = str + anios.ToString() + " años ";
      }
      if (meses > 0)
      {
      if (meses == 1)
      str = str + meses.ToString() + " mes y ";
      else
      str = str + meses.ToString() + " meses y ";
      }
      if (dias > 0)
      {
      if (dias == 1)
      str = str + dias.ToString() + " día ";
      else
      str = str + dias.ToString() + " días ";
      }
      return str;
      }

      Eliminar
    3. perfecto, alli identificando si es en plural o singular.

      Eliminar
  6. Bueno entonces un error que he arreglado y vengo a poner aqui para mejorar la version:

    El error:
    -FechaFin: 05/12/2013
    -FechaInicio: 29/04/2001
    -Respuesta de la Clase: 12 años, 7 meses y 7 días
    -Prueba de error: Utilizando la opcion de C# para aumentar días, meses y años:
    FechaInicio.AddDays(7).AddMonths(7).AddYears(12).ToString("dd/MM/yyyy");
    Arroja: 06/12/2013.
    Con esto probé que la clase su función pero se pasó por alto esto, dejo la clase arreglada:


    public String Diferencia(DateTime newdt, DateTime olddt)
    {
    int anos;
    int meses;
    int dias;
    string str = "";

    anos = (newdt.Year - olddt.Year);
    meses = (newdt.Month - olddt.Month);
    dias = (newdt.Day - olddt.Day);

    if (meses < 0)
    {
    anos -= 1;
    meses += 12;
    }

    if (dias < 0)
    {
    meses -= 1;
    int DiasAno = newdt.Year;
    int DiasMes = newdt.Month;

    if((newdt.Month - 1) == 0)
    {
    DiasAno = DiasAno - 1;
    DiasMes = 12;
    }
    else
    {
    DiasMes = DiasMes - 1;
    }

    dias += DateTime.DaysInMonth(DiasAno, DiasMes);
    }

    if (anos < 0)
    {
    return "La fecha inicial es mayor a la fecha final";
    }

    if (anos > 0)
    {
    if (anos == 1)
    str = str + anos.ToString() + " año ";
    else
    str = str + anos.ToString() + " años ";
    }

    if (meses > 0)
    {
    if (meses == 1)
    str = str + meses.ToString() + " mes y ";
    else
    str = str + meses.ToString() + " meses y ";
    }

    if (dias > 0)
    {
    if (dias == 1)
    str = str + dias.ToString() + " día ";
    else
    str = str + dias.ToString() + " días ";
    }

    return str;
    }

    ResponderEliminar
  7. eric dice que racing se la come

    ResponderEliminar
  8. Y para calcular cuándo las 2 fechas son las mismas? lo que pasa es que agrego las 2 fechas iguales, mismo mes,año y día, y me da de diferencia 365 días

    ResponderEliminar
  9. public String Diferencia(DateTime newdt, DateTime olddt)
    {
    int anos;
    int meses;
    int dias;
    string str = "";

    anos = (newdt.Year - olddt.Year);
    meses = (newdt.Month - olddt.Month);
    dias = (newdt.Day - olddt.Day);

    if (meses <= 0)
    {
    anos -= 1;
    meses += 12;
    }

    if (dias < 0)
    {
    meses -= 1;
    int DiasAno = newdt.Year;
    int DiasMes = newdt.Month;

    if((newdt.Month - 1) == 0)
    {
    DiasAno = DiasAno - 1;
    DiasMes = 12;
    }
    else
    {
    DiasMes = DiasMes - 1;
    }

    dias += DateTime.DaysInMonth(DiasAno, DiasMes);
    }

    if (meses == 12)
    {
    anos++;
    meses = 0;
    }

    if (anos < 0)
    {
    return "La fecha inicial es mayor a la fecha final";
    }

    if (anos > 0)
    {
    if (anos == 1)
    str = str + anos.ToString() + " año ";
    else
    str = str + anos.ToString() + " años ";
    }

    if (meses > 0)
    {
    if (meses == 1)
    str = str + meses.ToString() + " mes y ";
    else
    str = str + meses.ToString() + " meses y ";
    }

    if (dias > 0)
    {
    if (dias == 1)
    str = str + dias.ToString() + " día ";
    else
    str = str + dias.ToString() + " días ";
    }

    return str;
    }

    modifique para que calcule bien cuando coinciden los meses y años por ejemplo

    fecha inicio = 01-01-2017
    fecha final = 01-01-2017

    ahi debe dar 0 dias

    si quieren considerar el dia de hoy como dia completo hay que sumarle a enddate 1 dia

    espero les sirva saludos

    ResponderEliminar
  10. Esta Versión retorna los dos primeros valores de diferencia para el caso de poco espacio para mostrar, por ejemplo si la diferencia es en años muiestra años y meses, si es menor a un año muestra meses y días, si es menor a un mes muestra días y Horas, si es menor a un día muestra horas y minutos, si es menor a una hora muestra minutos y segundos.


    public static String Diferencia(DateTime newdt, DateTime olddt)
    {
    int a;
    int m;
    int d;
    TimeSpan dif = (newdt - olddt);
    string s = "";

    a = (newdt.Year - olddt.Year);
    m = (newdt.Month - olddt.Month);
    d = (newdt.Day - olddt.Day);

    if (m <= 0)
    {
    a -= 1;
    m += 12;
    }

    if (d < 0)
    {
    m -= 1;
    int DiasAno = newdt.Year;
    int DiasMes = newdt.Month;

    if ((newdt.Month - 1) == 0)
    {
    DiasAno = DiasAno - 1;
    DiasMes = 12;
    }
    else
    {
    DiasMes = DiasMes - 1;
    }

    d += DateTime.DaysInMonth(DiasAno, DiasMes);
    }

    if (m == 12)
    {
    a++;
    m = 0;
    }

    if (a < 0)
    {
    return "La fecha inicial es mayor a la fecha final";
    }



    if (a > 0)
    {
    if (a == 1)
    s = s + a.ToString() + " año ";
    else
    s = s + a.ToString() + " años ";

    if (m == 1)
    s = s + m.ToString() + " mes y ";
    else
    s = s + m.ToString() + " meses y ";

    return s;
    }

    if (m > 0)
    {
    if (m == 1)
    s = s + m.ToString() + " mes y ";
    else
    s = s + m.ToString() + " meses y ";

    if (d == 1)
    s = s + d.ToString() + " día ";
    else
    s = s + d.ToString() + " días ";

    return s;
    }

    if (d > 0 )
    {
    if (d == 1)
    s = s + d.ToString() + " día ";
    else
    s = s + d.ToString() + " días ";

    if (dif.Hours == 1)
    s = s + dif.Hours.ToString() + " Hora ";
    else
    s = s + dif.Hours.ToString() + " Horas ";

    return s;
    }


    if (dif.Hours > 0)
    {
    if (dif.Hours == 1)
    s = s + dif.Hours.ToString() + " Hora ";
    else
    s = s + dif.Hours.ToString() + " Horas ";

    if (dif.Minutes == 1)
    s = s + dif.Minutes.ToString() + " Minuto ";
    else
    s = s + dif.Minutes.ToString() + " Minutos ";

    return s;
    }

    if (dif.Minutes > 0)
    {
    if (dif.Minutes == 1)
    s = s + dif.Minutes.ToString() + " Minuto ";
    else
    s = s + dif.Minutes.ToString() + " Minutos ";

    if (dif.Seconds == 1)
    s = s + dif.Seconds.ToString() + " Segundo ";
    else
    s = s + dif.Seconds.ToString() + " Segundos ";

    return s;
    }

    if (dif.Seconds > 0)
    {
    if (dif.Seconds == 1)
    s = s + dif.Seconds.ToString() + " Segundo ";
    else
    s = s + dif.Seconds.ToString() + " Segundos ";

    if (dif.Milliseconds == 1)
    s = s + dif.Milliseconds.ToString() + " Milisegundo ";
    else
    s = s + dif.Milliseconds.ToString() + " Milisegundos ";

    return s;
    }

    return s;
    }

    ResponderEliminar