none
Calcular tiempo transcurrido TimeSpam RRS feed

  • Pregunta

  • Hola

    Necesito determinar el tiempo transcurrido hasta la media noche.

    Estos cálculos son correctos:

    Desde 11:00am Hasta 12:00pm = 01:00

    Desde 00:00am Hasta 11:00pm = 11:00

    Desde 11:00am Hasta 01:00pm = 02:00

    Pero cuando se calcula el siguiente tiempo el resultado no es correcto:

    Desde 11:00PM Hasta 00:00AM = -23:00

    Desde 11:00PM Hasta 12:00AM = -23:00

    Aquí esperaría que sea 01:00

    Eso es lo que realmente se requiere determinar, el tiempo transcurrido hasta la media noche.

    Lo estoy realizando de la siguiente manera:

       <asp:DropDownList ID="DropDownList1" runat="server">
            <asp:ListItem>00:00:00 AM</asp:ListItem>
            <asp:ListItem>11:00:00 AM</asp:ListItem>
            <asp:ListItem>12:00:00 PM</asp:ListItem>
             <asp:ListItem>10:00:00 PM</asp:ListItem>
            <asp:ListItem>11:00:00 PM</asp:ListItem>
        </asp:DropDownList>
        <asp:DropDownList ID="DropDownList2" runat="server">
             <asp:ListItem>00:00:00 AM</asp:ListItem>
            <asp:ListItem>11:00:00 AM</asp:ListItem>
            <asp:ListItem>12:00:00 PM</asp:ListItem>
             <asp:ListItem>01:00:00 PM</asp:ListItem>
            <asp:ListItem>12:00:00 AM</asp:ListItem>
            <asp:ListItem>11:00:00 PM</asp:ListItem>
        </asp:DropDownList>

      Dim horaInicio As DateTime = DropDownList1.SelectedItem.Text
            Dim horaFin As DateTime = DropDownList2.SelectedItem.Text
            Dim diferencia As TimeSpan = horaFin.Subtract(horaInicio)
            TextBox1.Text = diferencia.ToString()

    Gracias.



    Respuesta de foro Microsoft

    viernes, 25 de agosto de 2017 14:53

Respuestas

  • La primera sugerencia que te puedo hacer es que prendas la directiva 'Option Strict' (Option Strict On). Option Strict evitará -entre otras cosas- que intentes conversiones implícitas de un tipo String a un tipo DateTime, es una mala costumbre hacerlo. Si te fijas en el valor que obtienes en la variable 'horaFin' observarás que el valor de fecha es el valor mínimo para el tipo (algo como 01/01/0001 12:00:00) y sobre el valor mínimo no es posible restar una instancia de tiempo, motivo por el cual obtienes la excepción. Insisto en que la solución puede ser simple:

    Dim horaInicio = Convert.ToDateTime(DropDownList1.SelectedItem.Text).AddMinutes(-1)
    Dim horaFin = Convert.ToDateTime(DropDownList2.SelectedItem.Text).AddMinutes(-1)
    Dim diferencia As TimeSpan = horaFin.TimeOfDay.Subtract(horaInicio.TimeOfDay)

    Claro, lo mismo puedes hacer si en lugar de convertir a un tipo DateTime conviertes a la estructura TimeSpan, queda de ti ver que es lo mas conveniente.

     
    Nuestra profesión exige tener pasión por resolver problemas de una manera óptima y eficiente.
    • Editado Willams Morales viernes, 25 de agosto de 2017 18:26
    • Marcado como respuesta yulfredy viernes, 25 de agosto de 2017 19:11
    viernes, 25 de agosto de 2017 18:15

Todas las respuestas

  • Puedo explicar por qué falla, aunque no se me ocurre ninguna solución que sea fácil, rápida y elegante para remediarlo.

    El problema es que en el DopDownList tienes datos que contienen solo la hora (sin fecha), pero se los asignas a variables del tipo DateTime, que tienen hora y fecha. Cuando se hace esto, el sistema de forma predeterminada le mete la fecha del día actual. Esto implica que cuando comparas "Desde 11:00PM Hasta 00:00AM", en realidad estás comparando "desde HOY a las 11 hasta HOY (no MAÑANA) a las 00", lo cual supone retroceder 23 horas.

    Podrías hacer la chapucilla de añadir un "if" después de Dim horaFin As DateTime = DropDownList2.SelectedItem.Text para que si la hora es la medianoche se cambie la fecha por la del día siguiente.

    viernes, 25 de agosto de 2017 15:02
  • El resultado que obtienes es el esperado porque con 00:00 horas te refieres al inicio del mismo día y no del siguiente día como quizá esperas que suceda.

    Sí el limite superior es la media noche (siendo que el horario corresponde al día siguiente) restale un minuto antes de calcular la diferencia y luego vuelve a agregar la diferencia del tiempo, por ejemplo:

    Dim Diferencia = horaFin.AddMinutes(-1).TimeOfDay.Subtract(horaInicio.AddMinutes(-1).TimeOfDay)

    Edito.- Basta con igualar las condiciones en ambos factores.


    Nuestra profesión exige tener pasión por resolver problemas de una manera óptima y eficiente.

    viernes, 25 de agosto de 2017 15:26
  • graciasWillams Morales

    Al mometo de ejecutar genera el siguiente error:


    The added or subtracted value results in an un-representable DateTime.
    Parameter name: value


    Respuesta de foro Microsoft

    viernes, 25 de agosto de 2017 17:31
  • Hola

    Una solución que funciona correctamente para este caso fué sugerida en el siguiente link:

    https://es.stackoverflow.com/questions/97375/como-determinar-el-tiempo-transcurrido-hasta-la-media-noche?noredirect=1#comment180126_97375


    Respuesta de foro Microsoft

    viernes, 25 de agosto de 2017 17:32
  • hola

    El tema es que estas usando el concepto de hora de forma incorrecta, el TimeSpan representa una hora no un horario, o sea dices que son 3 hs no las 3 de la manana

    Para que una hora sea un horario debes ponerlo en el contexto del dia, o de un dia, por eso para trabajar la diferencia necesitas un DateTime, debes indicar que son las 3 am del dia x

    en tu aplicacion defines listas de horas no de horarios, tienes que adicionar el dia para que funcione

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 25 de agosto de 2017 17:42
  • La primera sugerencia que te puedo hacer es que prendas la directiva 'Option Strict' (Option Strict On). Option Strict evitará -entre otras cosas- que intentes conversiones implícitas de un tipo String a un tipo DateTime, es una mala costumbre hacerlo. Si te fijas en el valor que obtienes en la variable 'horaFin' observarás que el valor de fecha es el valor mínimo para el tipo (algo como 01/01/0001 12:00:00) y sobre el valor mínimo no es posible restar una instancia de tiempo, motivo por el cual obtienes la excepción. Insisto en que la solución puede ser simple:

    Dim horaInicio = Convert.ToDateTime(DropDownList1.SelectedItem.Text).AddMinutes(-1)
    Dim horaFin = Convert.ToDateTime(DropDownList2.SelectedItem.Text).AddMinutes(-1)
    Dim diferencia As TimeSpan = horaFin.TimeOfDay.Subtract(horaInicio.TimeOfDay)

    Claro, lo mismo puedes hacer si en lugar de convertir a un tipo DateTime conviertes a la estructura TimeSpan, queda de ti ver que es lo mas conveniente.

     
    Nuestra profesión exige tener pasión por resolver problemas de una manera óptima y eficiente.
    • Editado Willams Morales viernes, 25 de agosto de 2017 18:26
    • Marcado como respuesta yulfredy viernes, 25 de agosto de 2017 19:11
    viernes, 25 de agosto de 2017 18:15