segundos a HH:MM:SS

y programas personales para otros como tu, puede que te corrijan ;)
Responder
xapu
Hacker del Foro
Mensajes: 82
Registrado: 12 Dic 2009, 15:42

segundos a HH:MM:SS

Mensaje por xapu »

ola buenas!
bueno pues no se si existira algo parecido, pero lo necesitava para hacer un programilla y he creado esta funcion para pasar de segundos o milisegundos a formato HH:MM:SS

http://filebeam.com/7cd9a4f1acf95e0911698423bfee27d2

su uso es muy sencillo..
el primer parametro es el tiempo en segundos o milisegundos, si lo introduces en milisegundos deves poner un 1 en el segundo parametro, si no pon cualquier otro numero XD

Código: Seleccionar todo

#include "HMS.au3"
$tiemp = _segstoSMH(3800,0)
MsgBox(0,"segundos descompuestos:","horas: "&$tiemp[1]&" minutos: "&$tiemp[2]&" segundos: "&$tiemp[3])
estoy seguro de que tendra algun fallo.... si alguien ve alguno que lo postee aqui y que ponga su correcion si la hace
grax por colaborar
- 0 error(s), 0 warning(s) :smt098 FUCK YEA!
http://xapus.blogspot.com/
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: segundos a HH:MM:SS

Mensaje por Chefito »

No esta mal que intentes hacer una función así. Un gran esfuerzo por tu parte :smt024 .
Pero a mi parecer no es la mejor forma de hacer esto. Utilizas mucho los strings y el tratamiento de éstos. Esta no es la mejor forma. A mi parecer debes intentarlo con operaciones matemáticas (encima así es mucho más rápida la ejecución).
Además, revisala mejor porque los segundos te los devuelve mal. Incluso en el ejemplo que pones 3800 sg. son 1 hora, 3 minutos y 20 segundos, no 0 sg :smt016 .

Cogiendo tu función, he hecho una a mi estilo. Espero que te guíe. Si no entiendes algo y te interesa saber lo que hace alguna parte dimelo.
Editado el codigo después de las recomendaciones :smt003

Código: Seleccionar todo

;===============================================================================
;
; Function Name:    _cSgAhms($sg_mlsg,$formato=0)
; Description:      pasa los segundos o milisegundos a formato HH:MM:SS o HH:MM:SS:::MMM.
; Parameter(s):     $sg_mlsg       - segundos o milisegundos a pasar al formato anterior.
;                   [obl] $formato - (1)el tiempo esta en milisegundos 
;                   [opt] $formato - (0)el tiempo esta en segundos (Por defecto)
; Requirement(s):   AutoIt v. 3.3.6.0
; Return Value(s):  On Success -    devuelve un array de 5 elementos:
;                           $Elemento[0] devuelve la hora en formato HH:MM:SS:::MMM
;                           $Elemento[1] devuelve las horas
;                           $Elemento[2] devuelve los minutos
;                           $Elemento[3] devuelve los segundos
;                           $Elemento[4] devuelve los milisegundos.
;               Si la función falla porque el parámetro $sg_mlsg no es un número entero devuelve @error y la función 0.
; Example : $tiempo = _cSgAhms(3800)
;          $tiempo[0] valdra 01:03:20:::0
;          $tiempo[1] valdra 1 (1 hora)
;          $tiempo[2] valdra 3 (3 minutos)
;         $tiempo[3] valdra 20 (20 sg.)
;         $tiempo[4] valdra 0 (0 mlsg.)
; Remarks(s):    -Si eliges el formato=0 (tiempo en sg.) el elemento 5 ($Elemento[4]) devuelve siempre 0 (logicamente ;) ).
; Author(s):      Chefito, ayudado por Fredinchy y Ximorro.
; E-mail(s):      Moderador del foro www.autoit.es
;
;===============================================================================

Func _cSgAhms($sg_mlsg,$formato=0)
	Local $time[5]=[0,0,0,0,0], $sgOrMlsg=1
	If StringIsDigit($sg_mlsg)=0 Then       ;si no es un número válido, salta este error. Devuelve @error=1 y la función 0. 
		ConsoleWriteError(">>>> El número dado no tiene el formato adecuado. Debe ser todo dígitos.")
		Return SetError(1,0,0)
	EndIf
	If $formato Then      ;si formato=1 ($sg_mlsg son mlsg.) recupero los milisegundos
		$sg_mlsg=$sg_mlsg/1000
		$parteDecimal=StringSplit($sg_mlsg,".")
		If $partedecimal[0]>1 Then
			$time[4]=Number($parteDecimal[2])
			$sg_mlsg=Int($sg_mlsg)
		EndIf
	EndIf
	$time[1]=Int($sg_mlsg/3600)      ;averiguo las horas.
	$resto=Mod($sg_mlsg,3600)
	If $resto Then               ;si el resto no es 0 significa que hay minutos o sg. y entra en esta condición
		$time[2]=Int($resto/60)      ;averiguo los minutos.
		$resto=Mod($resto,60)
		If $resto Then            ;si el resto no es 0 significa que hay sg. y entra en esta condición
			$time[3]=$resto         ;averiguo los sg.
		EndIf
	EndIf   
   ;consigo el elemento 0 ($time[0]).
	If $time[1]<10 Then 
		$time[0]="0" & $time[1]
	Else
		$time[0]=$time[1]
	EndIf
	If $time[2]<10 Then 
		$time[0]=$time[0] & ":0" & $time[2]
	Else
		$time[0]=$time[0] & ":" & $time[2]
	EndIf
	If $time[3]<10 Then 
		$time[0]=$time[0] & ":0" & $time[3]
	Else
		$time[0]=$time[0] & ":" & $time[3]
	EndIf
    If $formato Then            ;si formato=1 entra en la condición y pone en el elemento 0 ($time[0]) ::: más los mlsg.
		If $time[4]<10 Then 
			$time[0]=$time[0] & ":::0" & $time[4]
		Else
			$time[0]=$time[0] & ":::" & $time[4]
		EndIf
	EndIf
   Return $time
EndFunc
Saludos y sigue así.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Fredinchy
Aprendiz de Mago
Mensajes: 32
Registrado: 30 Mar 2010, 01:27
Ubicación: Unknown

Re: segundos a HH:MM:SS

Mensaje por Fredinchy »

Hola!! yo de chismoso pasando por aquí me dio por probar la función modificada pero no me funcionó del todo.. osea funcionó a medias :smt005 ..

Me refiero a que si pruebas la función así:

Código: Seleccionar todo

$tiempo = _cSgAhms(3800,1)
Funciona! Pero si nos ponemos a jugar un poco modificando el número cuando el segundo parámetro es 1 da error la función :smt002
Ejm:

Código: Seleccionar todo

$tiempo = _cSgAhms(38000,1)
Y también otros números como el 1000, etc..

El error es:

Código: Seleccionar todo

C:\Users\FREDINCHY\Desktop\ayuda.au3 (44) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$time[4]=Number($parteDecimal[2])
$time[4]=Number(^ ERROR
Error del StringSplit() sino me equivoco

Y bueno por practicar un poco (aja soy amante de romperme el coco :smt035 ) pues me puse a hacer la función yo..

Aquí esta:

Código: Seleccionar todo

Func _SecToHMS($S_Number,$S_Format=0)
	Local $S_Time[5], $S_Mil=0

	If IsNumber($S_Number) = 0 Then
		ConsoleWriteError(">>>> El número dado no tiene el formato adecuado. Debe ser todo dígitos.")
		Return SetError(1,0,0)
	EndIf

	If $S_Format = 1 Then
		$S_Number2=$S_Number/1000
		$S_Mil=StringInStr($S_Number2,'.')
		$S_Number=$S_Number2
	EndIf

	$S_Hour=Int($S_Number/3600)
	$S_Mod=Mod($S_Number,3600)

	If $S_Hour < 10 Then
		$S_Hour=0&$S_Hour
	EndIf

	$S_Min=Int($S_Mod/60)

	If $S_Min < 10 Then
		$S_Min=0&$S_Min
	EndIf

	$S_Sec=Int(Mod($S_Mod,60))

	If $S_Sec<10 Then
		$S_Sec=0&$S_Sec
	EndIf

	$S_Time[1]=$S_Hour
	$S_Time[2]=$S_Min
	$S_Time[3]=$S_Sec

	If $S_Mil = 0 Then
		$S_Mil=StringTrimLeft($S_Mod,2)
	Else
		$S_Mil=StringTrimLeft($S_Number2,$S_Mil)
	EndIf

	$S_Mil=StringLeft($S_Mil,2)

	$S_Time[4]=$S_Mil

	If $S_Format = 1 Then
		$S_Time[0]=$S_Hour&':'&$S_Min&':'&$S_Sec&':'&':'&':'&$S_Mil
	Else
		$S_Time[0]=$S_Hour&':'&$S_Min&':'&$S_Sec
	EndIf

	Return $S_Time
EndFunc
Y no fueron tan malos los resultados.. es 25% más rápida que la modificada (hay que alardear con lo bueno ;D), pero como a mi siempre hay algo que me sale mal (ya estoy acostumbrado :smt005 ) pues tiene que tener sus bugs.. A propósito disculpen por no comentar el código.

Si hago esto:

Código: Seleccionar todo

$result= _SecToHMS(1000,1)
En milisegundos devolvió nada.. ni idea.. igual pasa con otros números con varios ceros como 3000, pero si colocas 3010 si funciona.. en fin quizá sea mejor idea modificar esta ya que trabaja más rápido.. pero seguro que hay formas de hacerlo más rápido aún.. Vamos aún ando novato no sé si esta sea la mejor forma de hacerlo..

PD: Para sacar los segundos hice trampa y miré el código de la función modificada.. :smt003 :3

Saludos!
Cause no one here can ever stop us! They can try but we won't let them! No way.. :smt020
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: segundos a HH:MM:SS

Mensaje por Ximorro »

Este último también tiene sus cosas, por ejemplo si se indica milisegundos pero no hay (por ejemplo _SecToHMS(3000,1) ) la cadena de los milisegundos está vacía, creo que debería ser 0 en el valor numérico, y en la cadena o es cero o se quitan los tres ":".
Además de que no pones valores numéricos (son cadenas) en los elementos por separado, como creo que era la idea...
Por cierto, si por ejemplo pongo _SecToHMS(3599,0) en $S_Time[4] me sale que hay 99 milisegundos, cuando deberían ser cero...

Una cosa, yo trabajaría numéricamente con las divisiones, los Int y los Mod para los valores por separado en $S_Time[1] a $S_Time[4], y al final para calcular $S_Time[0] lo juntaría todo con un StringFormat (o dos, dependiendo de si hay que poner milisegundos o no), por ejemplo sin milisegundos:

Código: Seleccionar todo

$hora = 5
$min = 10
$seg = 3
$cadena = StringFormat("%02u:%02u:%02u", $hora, $min, $seg)

Pues sí que se está resistiendo este programilla. Yo me pongo a sacar lo de los decimales sin pasar por strings, por intentar hacerlo más rápido, y se me ocurre esto:

Código: Seleccionar todo

$num = 34.23
$entera = Int($num)
$decimal = $num - $entera
Ojo que no está acabado, falta escalar decimal para que se haga entero. Pero no he llegado a eso, ese ejemplo me da:
num = 34
decimal = ¡¡0.229999999999997!!
Los típicos problemas de almacenar números decimales en binario... :smt013
Así que quizás no haya más remedio que usar strings

Una sugerencia para afinar ;-) Cuando el parámetro es en segundos ¿por qué no permitir decimales? El resultado entonces tiene milisegundos, aunque el parámetro se dé en segundos:
500.23 segundos = 8 minutos + 20 segundos + 230 milisegundos

Esta función la hice en otro lenguaje, estas son mis fórmulas para calcular los valores numéricos independientes (traducidas a AutoIt). No hace falta calcular valores intermedios ni tienen dependencias, cada valor se calcula desde el parámetro original (yo no usaba milisegundos, habría que sacar primero los decimales):

Código: Seleccionar todo

$tiempo = 500 ;los segundos a procesar
$hora = Floor($tiempo / 3600) ;División entera
$min = Mod(Floor($tiempo / 60), 60)
$seg = Mod($tiempo, 60)
ConsoleWrite(StringFormat("%02u:%02u:%02u", $hora, $min, $seg) & @CRLF)
Como estamos trabajando con valores positivos Floor e Int son equivalentes.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Fredinchy
Aprendiz de Mago
Mensajes: 32
Registrado: 30 Mar 2010, 01:27
Ubicación: Unknown

Re: segundos a HH:MM:SS

Mensaje por Fredinchy »

exacto ximorro en mi función hay problemas con los milisegundos.. pero ya era un poco tarde y no se me ocurría nada.. Estaba haciendo el código y cuando llegue ahí pues me enredé y por eso les mencione arriba los errores que daban los milisegundos.. Bueno después de ver el comentario de ximorro se me ocurrió algo.. Después de que vea una serie y coma me pondré a trabajar en ello..

Ah y cuando haces el ejemplo de _SecToHMS(3599,0) como el formato esta en cero pues sencillamente no debería calcular los milisegundos.. es un error mío en este condicional:

Código: Seleccionar todo

	If $S_Mil = 0 Then
		$S_Mil=StringTrimLeft($S_Mod,2)
	Else
		$S_Mil=StringTrimLeft($S_Number2,$S_Mil)
	EndIf
Porque si el formato no va a mostrar los milisegundos mejor es que ni los calcule.. y así es más rápido.. En fin en un rato me pongo en esto :smt024

Saludos!
Cause no one here can ever stop us! They can try but we won't let them! No way.. :smt020
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: segundos a HH:MM:SS

Mensaje por Chefito »

Juer......si que ha tenido éxito el tema :smt005 .
Bueno, como podeis ver he modificado mi función con vuestras recomendaciones :smt002 .
La verdad es que no la probé demasiado. No tenía ganas de estar probando y calculando tiempos :smt004 .
Fredinchy escribió:El error es:

Código: Seleccionar todo
C:\Users\FREDINCHY\Desktop\ayuda.au3 (44) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$time[4]=Number($parteDecimal[2])
$time[4]=Number(^ ERROR
Error del StringSplit() sino me equivoco
No te equivocas Fredinchy :smt023 . Se me pasó el poner un detector del error que podía causar el que al buscar decimales no tuviese ninguno y por esta causa no tuviese el elemento 2 el stringsplit. Gracias por comprobarlo.

Por cierto Fredinchy, me ha gustado la idea de que mirases la longitud del número buscando que fuese menor de 10, y encima es más rápido al ser una operación matemática!! Se me pasó esta posibilidad :smt021 . Por esta causa la he puesto en mi función. Por supuesto os he nombrado en ella :smt002 .

Lo de que tu función es más rápida que la mia....pues si te digo la verdad no las he comparado. Como he leído que aun falla en algunas cosas me esperaré a ver si la corriges y si quieres la comparamos :smt040 . Yo es que utilizo muchas comparaciones cuando no hay ni horas ni minutos ni segundos. Puede que esto y alguna cosa más (no se si el stringsplit relentizará mucho) la hagan algo más lenta. Pero vamos, no lo veo muy importante :smt003 .

Respecto a lo que dice Ximorro de restar el número entero al decimal para conseguir la parte decimal, ya lo probé yo y me paso lo mismo que a tí :smt005 . Vi que daba decimales. Se me ocurrió utilizar Round con una precisión de 3 decimales ya que se trabajan con milésimas, pero al final no lo hice así. Aunque sería otra posibilidad.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Fredinchy
Aprendiz de Mago
Mensajes: 32
Registrado: 30 Mar 2010, 01:27
Ubicación: Unknown

Re: segundos a HH:MM:SS

Mensaje por Fredinchy »

Disculpen la tardanza es que tuve problemas con otra computadora de la casa y las estaba arreglando :smt021 .

Bueno ya terminé mi función sin más que decir ahí les va:

Código: Seleccionar todo

Func _SecToHMS($S_Number,$S_Format=0)
	Local $S_Time[5], $S_Mil=0

	If IsNumber($S_Number) = 0 Then
		ConsoleWriteError(">>>> El número dado no tiene el formato adecuado. Debe ser todo dígitos.")
		Return SetError(1,0,0)
	EndIf


	If $S_Format = 1 Then
		$S_N=$S_Number
		$S_Number=$S_Number/1000
		$S_Ent = Floor($S_Number)
		$S_Dec = $S_Number - $S_Ent
		If $S_N < 100 Then
			$S_Dec=$S_Dec*100
		Else
			$S_Dec=$S_Dec*10
		EndIf
		If $S_Dec < 10 And $S_Dec > 1 Then
			$S_Dec=0&$S_Dec
		EndIf
		$S_Time[4]=$S_Dec
	EndIf

	If StringInStr($S_Number,'.')=True Then
		$S_Ent = Floor($S_Number)
		$S_Dec = Round($S_Number - $S_Ent,3)
		If $S_Dec < 100 Then
			$S_Dec=$S_Dec*100
		Else
			$S_Dec=$S_Dec*10
		EndIf
		If $S_Dec < 10 And $S_Dec > 1 Then
			$S_Dec=0&$S_Dec
		EndIf
		$S_Time[4]=$S_Dec
	EndIf

	$S_Hour=Int($S_Number/3600)
	$S_Mod=Mod($S_Number,3600)

	If $S_Hour < 10 Then
		$S_Hour=0&$S_Hour
	EndIf

	$S_Min=Int($S_Mod/60)

	If $S_Min < 10 Then
		$S_Min=0&$S_Min
	EndIf

	$S_Sec=Int(Mod($S_Mod,60))

	If $S_Sec<10 Then
		$S_Sec=0&$S_Sec
	EndIf

	$S_Time[1]=$S_Hour
	$S_Time[2]=$S_Min
	$S_Time[3]=$S_Sec

	If $S_Format = 1 Then
		$S_Time[0]=$S_Hour&':'&$S_Min&':'&$S_Sec&':'&':'&':'&$S_Dec
	Else
		$S_Time[0]=$S_Hour&':'&$S_Min&':'&$S_Sec
	EndIf

	Return $S_Time
EndFunc
Una sugerencia para afinar ;-) Cuando el parámetro es en segundos ¿por qué no permitir decimales? El resultado entonces tiene milisegundos, aunque el parámetro se dé en segundos:
500.23 segundos = 8 minutos + 20 segundos + 230 milisegundos
Buena sugerencia ya la incorporé.. :smt023

Ahora si vamos a la velocidad con un timerintit() y timerdiff() arrojan los siguiente:
Modificada por chefito 0.1611.......
Fredinchy 0.1451.......

La diferencia es mínima 0.02 segundos prácticamente y eso que mi función tiene añadida la sugerencia de Ximorro!! Gané!!.......... :smt046

Pues NO porque aunque le agregue código prácticamente no influye si no se usa y si le quitamos a la función de Chefito el for para declarar time[$n] la velocidad es 0.1306 es decir casi 19% más rápido que con el for.. Así que declaren las variables ustedes mismos no sean flojos :smt005 .

Saludoss!! :3
Cause no one here can ever stop us! They can try but we won't let them! No way.. :smt020
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: segundos a HH:MM:SS

Mensaje por Chefito »

Jajajajaja.......bueno, considero que has ganado :smt002 .
Ya te dije que casi no merecía la pena el intentar reducir el tiempo de la función. Fijate lo que tardan, aproximadamente 0,15 sg. (eso practicamente no es nada).
Pero si verdaderamente quieres comprobar la velocidad de una función se tiene que comprobar con todos los casos (o por lo menos varios casos), intentarlo con la memoria limpia, primero uno, luego el otro y al revés, etc. Pero como ya te he dicho con esto no merece la pena :smt005 .
Estos estudios están bien para optimizar funciones que pueden ser verdaderamente lentas por alguna razón (recursividades grandes, calculos matemáticos, operaciones grandes en bbdd, manejo de gráficos, etc). Pero te apoyo en que si cualquier función está bien optimizada para ganar velocidad...mejor que mejor :smt002 .
Para que sea más rápida esta función, se podría separar la que calcula el tiempo HH:MM:SS y HH:MM:SS:MM. También se podría quitar comprobaciones de errores. Aunque con este último cambio considero que entonces no sería una función bien declarada. Y mirar con más detenimiento el código para ver que se puede optimizar. Aunque en esta función poco se puede optimizar ya :smt005 .
Fredinchy escribió:Pues NO porque aunque le agregue código prácticamente no influye si no se usa y si le quitamos a la función de Chefito el for para declarar time[$n] la velocidad es 0.1306 es decir casi 19% más rápido que con el for.. Así que declaren las variables ustedes mismos no sean flojos .
Jajajajajajaja.....vale vale, he quitado el for y he declaro el array al principio :smt005 . No te fies mucho de eso. Puede que haya ganado ese ínfima velocidad por alguna razón.....porque en ese mismo momento el estado del ordenador fuese mejor por alguna razón :smt002 .

Saludos y buen trabajo.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: segundos a HH:MM:SS

Mensaje por Ximorro »

Bueno bueno, ¡vais a acabar con la función perfecta! ;-)

Está muy bien optimizar, pero como dice Chefito, cuando la cosa no es crítica es mejor no pasarse si el código va a quedar poco legible. Es mejor que esté más clarito aunque vaya un pelín más lento.

Puestos a optimizar:
S_Sec&':'&':'&':'&$S_Dec se puede poner como S_Sec&':::'&$S_Dec ¡JA JA JA!

Na, es broma, la has mejorado mucho y lo de permitir decimales creo que amplía bastante la funcionalidad, gracias por implementarlo.

Un par de sugerencias para afinar, en realidad una es un bug:
El bug es que lo de los segundos con decimales no va del todo bien, por ejemplo _SecToHMS(100.5,0) devuelve 50ms, cuando son 500. Además en este caso, al haber milisegundos, ¿no se debería devolver la cadena "00:01:40:::500" en vez de sólo "00:01:40"

La sugerencia es no ser tan estricto con la entrada, por ejemplo _SecToHMS("100",0) dice que "Debe ser todo dígitos". Ciertamente es un string, no un número, pero dado que AutoIt es tan poco tipado y puedes juntar cadenas y números con demasiada facilidad, yo permitiría números en string.
Con IsNumber miras que la variable sea numérica, quizás tocaría usar StringIsFloat y StringIsInt cuando sea String, o más fácil, lo pasas a número con Number, si da cero y la cadena no es "0" o lo consideras un error o devuelves cero segundos...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Fredinchy
Aprendiz de Mago
Mensajes: 32
Registrado: 30 Mar 2010, 01:27
Ubicación: Unknown

Re: segundos a HH:MM:SS

Mensaje por Fredinchy »

Vaya! a ximorro si que le gusta ponerme a trabajar.. jeje
S_Sec&':'&':'&':'&$S_Dec se puede poner como S_Sec&':::'&$S_Dec ¡JA JA JA!
De esto me di cuenta despues de colgar el código.. no sé porque razón agarré &':' y lo pegué 3 veces :smt005 !
El bug es que lo de los segundos con decimales no va del todo bien, por ejemplo _SecToHMS(100.5,0) devuelve 50ms, cuando son 500.
Este bug lo hice yo mismo.. exacto a propósito para trabajar con 2 números.. pero ahora que lo pienso no es lo mismo 50ms que 500ms :smt002
Además en este caso, al haber milisegundos, ¿no se debería devolver la cadena "00:01:40:::500" en vez de sólo "00:01:40"
Recuerda que aunque existan milisengundos en el número lo que determina si es HH:MM:SS:::MMM o HH:MM:SS es el segundo parámetro de la función, o sea el formato.. si se quiere usar los milisegundos con formato 0 para eso está el array[4].. Bueno pero esto para seguir la idea de la función original de xapu
Con IsNumber miras que la variable sea numérica, quizás tocaría usar StringIsFloat y StringIsInt cuando sea String, o más fácil, lo pasas a número con Number, si da cero y la cadena no es "0" o lo consideras un error o devuelves cero segundos...
Esta y las demás recomendaciones las implementaré mañana.. sobre todo la primera................ :smt046

Saludos y gracias por dar a conocer los bugs! :smt023
Cause no one here can ever stop us! They can try but we won't let them! No way.. :smt020
Avatar de Usuario
Fredinchy
Aprendiz de Mago
Mensajes: 32
Registrado: 30 Mar 2010, 01:27
Ubicación: Unknown

Re: segundos a HH:MM:SS

Mensaje por Fredinchy »

Ya tengo listo lo que esperemos que sea el código final de esta función
Editado el 31/5/2010 (agregado el fixed #4):

Código: Seleccionar todo

Func _SecToHMS($S_Number, $S_Format = 0)
	Local $S_Time[5], $S_Mil = 0

	If Number($S_Number) = 0 Then
		ConsoleWriteError(">>>> El número dado no tiene el formato adecuado. Debe ser todo dígitos. O el número es cero")
		Return SetError(1, 0, 0)
	EndIf

	If $S_Format = 1 Then
		$S_N = $S_Number
		If $S_Number < 1000 Then
			If $S_N < 10 Then
				$S_Dec = '00' & $S_N ; se coloca con '' porque si se coloca 00 solo se toma en cuenta un 0
			ElseIf $S_N >= 10 And $S_N < 100 Then
				$S_Dec = 0 & $S_N
			Else
				$S_Dec = $S_N
			EndIf
			$S_Time[1] = 00
			$S_Time[2] = 00
			$S_Time[3] = 00
			$S_Time[4] = $S_Dec
			$S_Time[0] = '00:00:00:::' & $S_Dec
			Return $S_Time
		Else
			$S_Number = $S_Number / 1000
			$S_Ent = Floor($S_Number)
			$S_Dec = $S_Number - $S_Ent
			If $S_N < 100 Then
				$S_Dec = $S_Dec * 100
			Else
				$S_Dec = $S_Dec * 10
			EndIf
			If $S_Dec < 10 And $S_Dec > 1 Then
				$S_Dec = 0 & $S_Dec
			EndIf
			$S_Time[4] = $S_Dec
		EndIf
	EndIf

	If StringInStr($S_Number, '.') = True Then
		$S_Ent = Floor($S_Number)
		$S_Dec = Round($S_Number - $S_Ent, 3)
		$S_Time[4] = $S_Dec * 1000
		$S_Dec=$S_Time[4]
	EndIf

	$S_Hour = Int($S_Number / 3600)
	$S_Mod = Mod($S_Number, 3600)

	If $S_Hour < 10 Then
		$S_Hour = 0 & $S_Hour
	EndIf

	$S_Min = Int($S_Mod / 60)

	If $S_Min < 10 Then
		$S_Min = 0 & $S_Min
	EndIf

	$S_Sec = Int(Mod($S_Mod, 60))

	If $S_Sec < 10 Then
		$S_Sec = 0 & $S_Sec
	EndIf

	$S_Time[1] = $S_Hour
	$S_Time[2] = $S_Min
	$S_Time[3] = $S_Sec

	If $S_Format = 1 Then
		$S_Time[0] = $S_Hour & ':' & $S_Min & ':' & $S_Sec & ':::' & $S_Dec
	Else
		$S_Time[0] = $S_Hour & ':' & $S_Min & ':' & $S_Sec
	EndIf

	Return $S_Time
EndFunc   ;==>_SecToHMS
Resumen:

Fixed #1: ':::'

Código: Seleccionar todo

$S_Time[0] = $S_Hour & ':' & $S_Min & ':' & $S_Sec & ':::' & $S_Dec
Fixed #2: Agregado un condicional para arreglar bug de la versión anterior al introducir milisegundos menores de 1000.

Código: Seleccionar todo

If $S_Number < 1000 Then [...]
Fixed #3: Implementado Number() al entrar en la función..

Código: Seleccionar todo

If Number($S_Number) = 0 Then
Fixed #4: Agregado $S_Dec=$S_Time[4] para arreglar bug de milisegundos.. (Edit 31/5/2010)

Ahora si no esta perfecta esta bastante cerca :smt003 !
Bueno gracias por detectar bugs importantes y por las recomendaciones :smt026

Saludos! :3
Última edición por Fredinchy el 01 Jun 2010, 03:10, editado 1 vez en total.
Cause no one here can ever stop us! They can try but we won't let them! No way.. :smt020
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: segundos a HH:MM:SS

Mensaje por Ximorro »

Estooooo, mejora mucho pero aún hay un pequeño bug... que conste que no es por fastidiar...

Si pongo por ejemplo _SecToHMS(1500,1) devuelve la cadena 00:00:01:::0.5.
Los milisegundos deberían ser 500, no 0.5, sólo pasa en el string, en el valor numérico del array está bien.

Lo del formato de salida es cosa de interpretación. Yo entendía que ese parámetro es para indicar el formato de la entrada, y que la salida dependería de si hay milisegundos o no. Pero vaya, también lo puedes tomar como formato de salida, además de el de entrada, el programador elige. Eso sí, mejor si lo documentas ;-)
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Responder