Página 1 de 1

Re: Temporizador basado en la hora

Publicado: 16 Oct 2009, 17:14
por Jonny
Hola

¡Casi os escribo desde el loquero! jeje.

Resulta, que estoy implementando la función para calcular un timeout, que hizo Chefito en este post hace algún tiempo ya.
Ahsta ahora, la función había ido de lujo, pero por casualidad, dí con un fallo que me ha costado encontrar, por lo raro que es.
Resulta, que pasándole a la función 60 segundos o más, parece calcular bien el timeout (digo parece, porque no lo probé con todos los valores posibles jeje).
El problema viene, al pasarle un valor inferior a 60 sg. desde 59 sg hasta 15 (ambos inclusibes) devuelve una hora incorrecta. Por ejemplo, recientemente he hecho una prueba, en la que le pasé 55 segundos y esto es lo que obtube:
Hora actual: 17:04:25
Timeout: 17:04:20
Hora actual es cuando ejecuté el script y Timeout es la hora que ha calculado la función tras sumar los 55 segundos, que como veis parece que restó 5 más bien.
Lo mejor de todo, es que con valores inferiores a 15, funciona bien.

Capaz de funcionaros bien, como parece que ocurrió anteriormente, con alguna otra prueba que hice, que no me funcionaba, pero en cambio a Chefito sí.

Salu2!

Re: Temporizador basado en la hora

Publicado: 16 Oct 2009, 21:23
por Jonny
Hola

Creo que he arreglado el problema que posteaba hace un rato con la función del timeout, de Chefito´.

Analizando el código, he visto donde estaba el problema (o eso creo), (sigo sin entender muy bien el por que funcionaba con valores muy bajos (inferiores a 15 sg)) pero creo haberle encontrado almenos la lógica al que no funcionara.

Y esque, la función dice que si el valor que se recibe es inferior a 60 sg, se ajuste $HourResult[1] (minutos) a los minutos actuales del sistema
If $TimeOut>=60 Then
$HourResult[1]=Mod(@MIN+(Int($TimeOut/60)),60)
Else
$HourResult[1]=@MIN
EndIf
Por lo que al pasarle 55 segundos por ejemplo, se calcula el resto de los segundos, que está corecto, pero no se actualizan los minutos... que normalmente tendría que sumarse un minuto a menos que el valor de @Sec sea inferior a 5 ¿No?.

He arreglado (creo) la función para que al pasar un valor inferior a 60 sg se calculen los segundos, pero también se añadan los minutos que corresponda y las horas si corresponde.
Me ha costado bastante (toda una tarde) dejarla lo mejor que he sabido, pues el hecho de actualizar minutos suponía actualizar horas y entre tanto cálculo y tanto código, que si lo hago así, que si lo hago asá, siempre acababa por destrozar la función jejeje. Y cuanto más tiempo llevaba con ello más la destrozaba. Pero al fin parece haber salido algo potable.
No la he testeado a fondo, pero lo que he podido probar por el momento parece ir correctamente. Probad si quereis a ver que os parece (No me riñais mucho) si no está muy fina, que es viernes... jejeje.

Código: Seleccionar todo


Func SetTimeOut($TimeOut)

Local $HourResult[3]

If $TimeOut<0 Then Return 0

If $TimeOut==0 Then Return 0

If $TimeOut>=3600 Then

$HourResult[0]=Mod(@HOUR+(Int($TimeOut/3600)),24)

Else

$HourResult[0]=@HOUR

EndIf

If $TimeOut>=60 Then

$HourResult[1]=Mod(@MIN+(Int($TimeOut/60)),60)

EndIf

$HourResult[1]=@MIN

$CalcSec=Int((@Sec+$TimeOut)/60)

$HourResult[1]+=$CalcSec

$HourResult[2]=Mod(@SEC+$TimeOut,60)

$CalcMin=Int($HourResult[1]/60)

$HourResult[0]+=$CalcMin

$HourResult[0]=Mod($HourResult[0], 24)

$HourResult[1]=Mod($HourResult[1], 60)

For $N=0 to 2

If StringLen($HourResult[$N])==1 Then

$HourResult[$N]="0"&$HourResult[$N]

EndIf

Next

Return $HourResult[0]&":"&$HourResult[1]&":"&$HourResult[2]

EndFunc

$Timeout=SetTimeout(55)

msgbox(0, "", @Hour&":"&@Min&":"&@Sec&@CRLF&$Timeout)

 
He puesto los malditos 55 segundos en la llamada a la función como ejemplo, para que veais que devuelve la hora actual y la calculada por la función correctamente. Falta testear que pasaría si fueran las 23:59:45 y se le pasaran más de 15 segundos (debería responder correctamente, pero a saber.... En el fin de semana o el lunes lo pruebo.

Salu2!

Re: Temporizador basado en la hora

Publicado: 18 Oct 2009, 15:05
por Chefito
Mira tu función que la he visto y da fallos por todos los lados :smt005 . Utiliza valores un poco más altos y verás. Un ejemplo, pasale dos horas (7200 segundos).

Mmmmm....tienes razón. Miré mi función más detenidamente y hace aguas por algunos sitios :smt005 .
He podido corregir facilmente el error de los segundos. También vi que a los minutos y horas le pasaba algo parecido. Y para rematar tampoco resolvía bien el paso de hora de un día a otro :smt021 .
Al final vi que se complicaba demasiado el código y opté por enfocarlo de otro modo.
Os dejo la nueva función, mucho más corta y menos liosa.
Aquí lo que hago es pasar la hora actual a segundos y sumarle los segundos que le damos a la función. A partir de ahí empiezo ha averiguar las horas, minutos y segundo resultantes del total. Como veis el código es mucho más claro, más corto y "creo" que no falla (probarlo y ver si tiene algún fallo, que nunca se sabe :smt005 ).

Código: Seleccionar todo

Dim $hora

Func GetTimeOut($TimeOut)

    ;pequeño tratamiento de errores ;)=

    If IsInt($TimeOut)=0 Then

      ConsoleWriteError("Error número 0. El valor " &$TimeOut& " no es un número entero. ")

      Return SetError(0)

    ElseIf $TimeOut<0 Then

      ConsoleWriteError("Error número 1. El valor " &$TimeOut& " es un número negativo. Debe ser positivo. ")

      Return SetError(1)

    EndIf

    Local $HoraResult[3]   ;el elemento 0 son las horas, el 1 los minutos y el 2 los segundos.

    Local $TiempoTotalEnSg= (@HOUR*3600)+(@MIN*60)+@SEC+$TimeOut    ;convierto la hora actual en sg., y le sumo los segundos dados.

    $HoraResult[0]=Mod(Int($TiempoTotalEnSg/3600),24)    ;nos devuelve la hora resultante al sumar los sg. dados a la hora actual. 

    Local $minutos=Mod($TiempoTotalEnSg,3600)       ;nos devuelve los sg. sobrantes que no completan una hora.

    $HoraResult[1]=Int($minutos/60)         ;nos devuelve los minutos resultantes de sumar el tiempo pasado a la función a la hora actual.

    $HoraResult[2]=Mod($minutos,60)       ;nos devuelve los sg. resultantes de sumar el tiempo pasado a la función a la hora actual.

   For $n=0 to 2

      If StringLen($HoraResult[$n])=1 Then $HoraResult[$n]="0" & $HoraResult[$n]

   Next

   Return $HoraResult

EndFunc

;$hora=GetTimeOut(23900)

;MsgBox(0,"",@Hour&":"&@Min&":"&@Sec&@CRLF&$hora[0] & ":" & $hora[1] & ":" & $hora[2])

While 1

    Sleep(1000)

    $hora=GetTimeOut(7200)

    ConsoleWrite(@Hour&":"&@Min&":"&@Sec&" ; "&$hora[0] & ":" & $hora[1] & ":" & $hora[2]&@CR)

WEnd
Al principio lo hice con condiciones: La primera condición decía que si el total de segundos ($TiempoTotalEnSg) era mayor que 3599 (mayor que 59 minutos y 59 seguntos) hiciese la operación de resolución de horas, y si no que le pasase a las horas el valor 0 ($HoraResult[0]=0).
La condición de los minutos que si era mayor de 59 sg. que hiciese la operación para averiguar los minutos y si no que lo igualase a 0.
Y la condición de los sg., que si el módulo (resto) era distinto de 0 que hiciese la operación de los sg.
Pero las quité al ver que no eran muy importantes y que no habían demasiados casos para ahorrarte las operaciones.
Quien quiera que las ponga.

Saludos.

Re: Temporizador basado en la hora

Publicado: 18 Oct 2009, 22:21
por Jonny
Hola

Eso me pasó... que conforme iba arreglando cosas se complicaban otras, y con tanto número y tanta operación me volví loco. Al final era casi mejor hacer una función nueva. Yo, probé con valores pequeños, me quedaba testear a fondo con valores grandes etc.
Mañana pruebo esta nueva función y te cuento.
¡Gracias!.

Salu2!

Re: Temporizador basado en la hora

Publicado: 19 Oct 2009, 14:33
por Jonny
Hola.

He probado la función en medida de lo que he podido (y se me ha ocurrido) esta vez sí, parece funcionar. No se cuanto serán 23900 segundos (no lo calculé) pero son unas 6 horas y pico y tiene pinta de funcionar. Parece incluso hacer bien el cambio de días. Oséa, que con los valores pequeños y grandes que probé ha funcionado bien.

Salu2!