¿ Se puede hacer esta consulta de fechas ?

Iniciado por ostrede, 14 Agosto 2013, 02:58 AM

0 Miembros y 1 Visitante están viendo este tema.

ostrede

Hola, quiero hacer una consulta en vbnet de un intervalo de fechas. Quiero que me diga tal como lo siguiente:

Function sTiempo(dInicio As Date, dFin As Date) As String
sTiempo = Str((DateDiff("s", dInicio, dFin) \ 86400) Mod 365) & " días, "
sTiempo = sTiempo & Str((DateDiff("s", dInicio, dFin) \ 3600) Mod 24) & " horas, "
sTiempo = sTiempo & Str((DateDiff("s", dInicio, dFin) \ 60) Mod 60) & " minutos, "
sTiempo = sTiempo & Str(DateDiff("s", dInicio, dFin) Mod 60) & " segundos."
End Function


Lo que hace es calcular la diferencia en segundos y después ajustarla a dias, horas...

p.e. Imaginemos que en un TextBox (Text1) tienes una fecha en este formato "25/07/2007 15:00:00" y en otro (Text2) lo siguiente "26/07/2007 17:25:32"

Si haces una llamada a la función así:
Variable = sTiempo(Text1, Text2)
retornará la cadena "1 días, 2 horas, 25 minutos, 32 segundos."

Pero yo quiero que el intervalo me diga los meses, semanas y días.
Por ejemplo del 01/03/2013 al 10/04/2013 y me diga que hay 1 MES, 1 SEMANA y 3 DÍAS.


¿Se podría hacer?

Eleкtro

#1
Cita de: ostrede en 14 Agosto 2013, 02:58 AM¿Se podría hacer?

Así lo hice yo:

EDITO: He extendido la función para obtener horas, minutos y segundos.

Código (vbnet) [Seleccionar]
#Region " Date Difference "

    ' Date Difference
    '
    ' // By Elektro H@cker
    '
    ' Examples :
    '
    ' MsgBox(DateDifference(DateTime.Parse("01/03/2013"), DateTime.Parse("10/04/2013"))) ' Result: 1 Months, 1 Weeks, 2 Days, 0 Hours, 0 Minutes and 0 Seconds
    ' MsgBox(DateDifference(DateTime.Parse("01/01/2013 14:00:00"), DateTime.Parse("02/01/2013 15:00:30"))) ' Result: 0 Months, 0 Weeks, 1 Days, 1 Hours, 0 Minutes and 30 Seconds

    Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

        Dim MonthDiff As String, WeekDiff As String, _
            DayDiff As String, HourDiff As String, _
            MinuteDiff As String, SecondDiff As String

        MonthDiff = Convert.ToString(DateDiff("M", Date1, Date2))
        WeekDiff = Convert.ToString(DateDiff("d", Date1.AddMonths(DateDiff("M", Date1, Date2)), Date2) \ 7)
        DayDiff = Convert.ToString(DateDiff("d", Date1.AddMonths(DateDiff("M", Date1, Date2)), Date2) - (WeekDiff * 7))
        HourDiff = Convert.ToString(DateDiff("h", Date1.AddHours(DateDiff("h", Date1, Date2)), Date2) - (Date1.Hour - Date2.Hour))
        MinuteDiff = Convert.ToString(DateDiff("n", Date1.AddMinutes(DateDiff("n", Date1, Date2)), Date2) - (Date1.Minute - Date2.Minute))
        SecondDiff = Convert.ToString(DateDiff("s", Date1.AddSeconds(DateDiff("s", Date1, Date2)), Date2) - (Date1.Second - Date2.Second))

        Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
                             MonthDiff, WeekDiff, DayDiff, HourDiff, MinuteDiff, SecondDiff)

    End Function

#End Region


PD: Mi función no cuenta el primer día restante porque me parece incorrecto, del 1 al 7 no hay 7 días de diferencia, hay 6, si quieres obtener el resultado que comentas pues símplemente añade un "+ 1" a la diferencia de días.

Saludos!








ostrede

He probado el código pero cuando pongo por ejemplo del 15/08/2013 al 02/09/2013 me tira lo siguiente:

1 Months, -1 Weeks, -6 Days, 0 Hours, 0 Minutes and 0 Seconds

Debería decirme 2 semanas y 4 días.

No sé porqué sale la resta negativa y cómo solucionarlo.

Eleкtro

No me habia dado ningún error por el momento, pero vaya, tienes razón.

No se si podré solucionarlo, ya investigaré

saludos








Eleкtro

#4
Es reálmente necesario obtener el valor de las semanas?, los formatos de string standard de un DateTime no pueden obtener este valor...

Ahora lo he hecho de otra manera ya que el primer code no funcionaba con algunas fechas, pero el valor de las semanas no se me ocurre como obtenerlo:

CORREGIDO (eso creo, aun no he probado la modificación pero debería funcionar):
Código (vbnet) [Seleccionar]
   Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

       Dim MonthDiff As Long , _
          DayDiff As Long , HourDiff As Long , _
          MinuteDiff As Long , SecondDiff As Long

       MonthDiff = Date2.Month - Date1.Month
       DayDiff = Date2.Day - Date1.Day
       HourDiff = Date2.Subtract(Date1).Hours
       MinuteDiff = Date2.Subtract(Date1).Minutes
       SecondDiff = Date2.Subtract(Date1).Seconds
       'Dim MilliDiff As Long = Date2.Subtract(Date1).Milliseconds

       Return String.Format("{0} Months, {1} Days, {2} Hours, {3} Minutes and {4} Seconds", _
                             MonthDiff, DayDiff, HourDiff, MinuteDiff, SecondDiff)

   End Function


Saludos.








Novlucker

EleKtro H@cker, sin probarla, esa función no es correcta :P
¿Qué pasa si le paso como parámetros las fechas "01/01/2013 14:00:00" y "02/01/2013 13:00:30"?

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Eleкtro

Cita de: Novlucker en 15 Agosto 2013, 22:14 PM
EleKtro H@cker, sin probarla, esa función no es correcta :P
¿Qué pasa si le paso como parámetros las fechas "01/01/2013 14:00:00" y "02/01/2013 13:00:30"?

Saludos

Es verdad no me di cuenta, malditas "horas" xD

Bueno todo tiene solución, entonces hay que substraer en lugar de restar:

Código (vbnet) [Seleccionar]
    Dim HourDiff As Long = Date2.Subtract(Date1).Hours
    Dim MinuteDiff As Long = Date2.Subtract(Date1).Minutes
    Dim SecondDiff As Long = Date2.Subtract(Date1).Seconds
    Dim MilliDiff As Long = Date2.Subtract(Date1).Milliseconds


Llevo un lio tremendo para sacar la fecha con eficacia (por ejemplo entre meses como febrero con 28 días), el valor de las semanas se resiste, pero nadie tiene la solución: http://stackoverflow.com/questions/18259835/function-to-get-a-custom-date-difference

Saludos!








Novlucker

#7
A eso iba, cuando pasas al detalle de horas/minutos/segundos, entonces pasas a tener problemas a partir de los meses, porque un mes son 30,4368499 días según google :P

Había implementado un método pero tiene el mismo problema a partir del mes, por el tema de redondeo y demás (es el mismo método que se utiliza por ejemplo para dividir un importe en billetes).

Código (csharp) [Seleccionar]
public string DateDifference(DateTime dateStart, DateTime dateEnd)
{
   Dictionary<string, double> dateParts = new Dictionary<string, double>();
   dateParts.Add("Years", 31556925.97632);
   dateParts.Add("Months", 2629743.83136);
   dateParts.Add("Weeks", 604800);
   dateParts.Add("Days", 86400);
   dateParts.Add("Hours", 3600);
   dateParts.Add("Minutes", 60);
   dateParts.Add("Seconds", 1);

   TimeSpan time = dateEnd - dateStart;
   double totalSeconds = time.TotalSeconds;
   List<string> result = new List<string>();
   int diff;

   foreach (KeyValuePair<string, double> part in dateParts)
   {
       diff = (int)(totalSeconds / part.Value);
       totalSeconds -= (diff * part.Value);

       result.Add(string.Format("{0} {1}", diff, part.Key));
   }

   return string.Join(", ", result.ToArray());
}


Creo que se podría implementar el método, pero ya no es tan "sencillo"

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Eleкtro

La ciencia de "1 mes" no es exacta, son todo promedios, Google dice que son 30 días como ha dicho Novlucker, pero la Wikipedia dice que son 29, y nosotros cuando decimos un mes (al menos yo) pensamos en 30 días sin tener el cuenta el més en el que estamos, pero cuando decimos "el próximos més" pensamos en el día 1 del siguiente més, en fín por todo esto creo que no hay que comerse mucho la cabeza para intentar calcular al milímetro los meses.

Así que aquí dejo el code funcional para VB que me ha proporcionado una persona, el code funciona con la fecha problemática que ha comentado @ostrede y también con los horarios:

Código (vbnet) [Seleccionar]
#Region " Date Difference "

    ' Date Difference
    '
    ' Examples :
    '
    ' MsgBox(DateDifference(DateTime.Parse("01/03/2013"), DateTime.Parse("10/04/2013"))) ' Result: 1 Months, 1 Weeks, 2 Days, 0 Hours, 0 Minutes and 0 Seconds
    ' MsgBox(DateDifference(DateTime.Parse("01/01/2013 14:00:00"), DateTime.Parse("02/01/2013 15:00:30"))) ' Result: 0 Months, 0 Weeks, 1 Days, 1 Hours, 0 Minutes and 30 Seconds

    Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

        Dim Time As TimeSpan
        Dim MonthDiff As Integer, WeekDiff As Integer

        Do Until Date1 > Date2
            Date1 = Date1.AddMonths(1)
            MonthDiff += 1
        Loop

        MonthDiff -= 1
        Date1 = Date1.AddMonths(-1)
        Time = (Date2 - Date1)
        WeekDiff = (Time.Days \ 7)
        Time = (Time - TimeSpan.FromDays(WeekDiff * 7))

        Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
                             MonthDiff, WeekDiff, Time.Days, Time.Hours, Time.Minutes, Time.Seconds)

    End Function

#End Region


¿Tema solucionado? xD.

Saludos








ostrede

Cita de: EleKtro H@cker en 16 Agosto 2013, 02:13 AM
La ciencia de "1 mes" no es exacta, son todo promedios, Google dice que son 30 días como ha dicho Novlucker, pero la Wikipedia dice que son 29, y nosotros cuando decimos un mes (al menos yo) pensamos en 30 días sin tener el cuenta el més en el que estamos, pero cuando decimos "el próximos més" pensamos en el día 1 del siguiente més, en fín por todo esto creo que no hay que comerse mucho la cabeza para intentar calcular al milímetro los meses.

Así que aquí dejo el code funcional para VB que me ha proporcionado una persona, el code funciona con la fecha problemática que ha comentado @ostrede y también con los horarios:

Código (vbnet) [Seleccionar]
Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

       Dim Time As TimeSpan
       Dim MonthDiff As Integer, WeekDiff As Integer

       Do Until Date1 > Date2
           Date1 = Date1.AddMonths(1)
           MonthDiff += 1
       Loop

       MonthDiff -= 1
       Date1 = Date1.AddMonths(-1)
       Time = (Date2 - Date1)
       WeekDiff = (Time.Days \ 7)
       Time = (Time - TimeSpan.FromDays(WeekDiff * 7))

       Return String.Format("{0} Months, {1} Weeks, {2} Days, {3} Hours, {4} Minutes and {5} Seconds", _
                            MonthDiff, WeekDiff, Time.Days, Time.Hours, Time.Minutes, Time.Seconds)

   End Function


¿Tema solucionado? xD.

Saludos




¡¡ BUENÍSIMO !!
Ahora estoy trabajando con éste código para que me dé los meses, quincenas, semanas y días (con la salvedad que 1 mes lo cuente como 30 días, es así como lo quiero) pero creo que me estoy haciendo un lío.

Mi código es el siguiente( advierto que soy un novato en VBNET ):





Código (vbnet) [Seleccionar]
Private Function DateDifference(ByVal Date1 As DateTime, ByVal Date2 As DateTime) As String

        Dim Time As TimeSpan
        Dim MonthDiff As Integer, QuincenaDiff As Integer, weekdiff As Integer

        Do Until Date1 > Date2
            Date1 = Date1.AddDays(30)
            MonthDiff += 1

            Date1 = Date1.AddDays(15)
            QuincenaDiff += 1

            Date1 = Date1.AddDays(7)
            weekdiff += 1
        Loop

        MonthDiff -= 1
        Date1 = Date1.AddDays(-30)

        QuincenaDiff -= 1
        Date1 = Date1.AddDays(-15)

        weekdiff -= 1
        Date1 = Date1.AddDays(-7)

        Time = (Date2 - Date1)
        QuincenaDiff  = (Time.Days \ 15)
        Time = (Time - TimeSpan.FromDays(QuincenaDiff * 15))

        Time = (Date2 - Date1)
        weekdiff = (Time.Days \ 7)
        Time = (Time - TimeSpan.FromDays(weekdiff * 7))



        Return String.Format("{0} Months, {1} Quincenas, {2} weeks, {3} days, {4} Minutes and {5} Seconds", _
                             MonthDiff, QuincenaDiff, weekdiff, Time.Days, Time.Hours, Time.Minutes, Time.Seconds)

    End Function




Pero cuando por ejemplo pongo desde el 16/08/2013 al 31/08/2013 me tira 1 quincena, 2 semanas y 1 día. Cuando debería decir 1 quincena.

¿Qué estoy haciendo mal?.