Ir al contenido


Foto

Convertir un valor tipo Double en formato HH:MM


  • Por favor identifícate para responder
16 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 07 septiembre 2012 - 08:50

¿Es posible hacer lo que indico en el título con Delphi? ¿Se usaría con Format?. Por ejemplo:



delphi
  1. 6.25 - > 06:15



Saludos.
  • 0

#2 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 07 septiembre 2012 - 09:10

¿Algo así?


delphi
  1. var
  2.   f: Double;
  3. begin
  4.   f:= 6.25 / 24;
  5.   ShowMessage(FormatDateTime('hh:mm',TDateTime(f)));
  6. end;


  • 0

#3 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 07 septiembre 2012 - 10:07

mmm, Muy bueno, perooo, en algunos casos me da un minuto menos de lo que debería ser, ¿Por Qué?.

Saludos.
  • 0

#4 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 07 septiembre 2012 - 10:14

Me respondo:



delphi
  1. var
  2.   f: Double;
  3. begin
  4.   f:= (6.25 + 0.01) / 24;
  5.   ShowMessage(FormatDateTime('hh:mm',TDateTime(f)));
  6. end;



Ya los datos me dan exactos.

Saludos.
  • 0

#5 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 07 septiembre 2012 - 04:49

y por qué el + 0,01?? No lo entiendo :/

Yo también me encontré con este problema y decidí hacerlo de la manera tradicional, truncando y luego la parte fraccionaria multiplicando por 60
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 08 septiembre 2012 - 12:18

Pues no entiendo el porqué ha de sumarse ese 0.01.
¿Y que valores se obtiene, su ese incremento, con valores límites como: 5:00 o 7:59?

Saludos,
  • 0

#7 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 08 septiembre 2012 - 01:31

y por qué el + 0,01?? No lo entiendo :/


Sospecho que el problema es el redondeo de los decimales. Un minuto (en un TDateTime) es igual a 0,000694444444444444, y como "DecodeDate" utiliza multiplicaciones y divisiones enteras una simple diferencia, aunque sea muy pequeña, puede hacer que le falte un minuto. Por eso si aumentamos el valor de la variable en 0,01 (puede que incluso 0,001) la división ya nos da correcta.

No entiendo porque pascal utiliza esta forma de almacenar fechas, en otros lenguajes almacenan segundos, incluso milisegundos, como un entero. Ocupa mas sitio en memoria pero es indudable que es mucho mas preciso. ¿Otro misterio que habrá que investigar? :D
  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 08 septiembre 2012 - 12:27

Sospecho que el problema es el redondeo de los decimales. Un minuto (en un TDateTime) es igual a 0,000694444444444444, y como "DecodeDate" utiliza multiplicaciones y divisiones enteras una simple diferencia, aunque sea muy pequeña, puede hacer que le falte un minuto. Por eso si aumentamos el valor de la variable en 0,01 (puede que incluso 0,001) la división ya nos da correcta.

Pues si... no hay otra explicación pero de todas formas es extraño porque el tipo Double ya de por si es bastante preciso como para fallar en el orden de los 0,0001 cuando sus operaciones son exactas y aseguradas en los 13 decimales, dejando una ventana de "gracia" a los dos últimos.

No entiendo porque pascal utiliza esta forma de almacenar fechas, en otros lenguajes almacenan segundos, incluso milisegundos, como un entero. Ocupa mas sitio en memoria pero es indudable que es mucho mas preciso. ¿Otro misterio que habrá que investigar? :D

Uno puede utilizar el tipo TTimeStamp, que está pensado para trabajar con mejor precisión en el órden de los milisegundos. El tipo está pensado como un record, que almacena en formato entero la parte fecha y otro para la parte de la hora.
Es posible que por diseño TDateTime esté pensado para operaciones no más allá de los segundos y que sea justamente donde termina la precisión que ofrece el Double.

Se puede pasar de un TDateTime a TTimeStamp y a la inversa si uno lo necesita.

Saludos,
  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 08 septiembre 2012 - 07:02

Hola



delphi
  1. var
  2.   numeroStr: string;
  3.   numero: float;
  4.  
  5. begin
  6.   numero: 6.1;
  7.   numeroStr := FormatFloat('00.00',Numero);
  8.   numeroStr := StringReplace(numeroStr,'.',':',[rfReplaceAll]);
  9.   shoMessage( numeroStr );
  10. end;



Saludos

  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 08 septiembre 2012 - 09:50

Ummm...
Eliseo no he probado tu código pero creo no va...
Me temo que no es tan simple la cosa. Porque lo que dice Fernando es dado el número en real "normalizado a horas" (por darle un nombre  :p ) obtener su expresión en formato hh:mm.

De allí que, por ejemplo:

4.25 son las 04:15
6.5 son las 06:30
17.75 son las 17:45

Es decir, donde la parte entera corresponde a las horas, mientras que la decimal a los minutos.
Tu propuesta toma literalmente el número y asume que la parte decimal es exactamente los minutos.

La otra es diseñar una función propia que extraiga cada parte y haga la conversión de la parte decimal a los minutos.

Saludos,
  • 0

#11 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 08 septiembre 2012 - 10:21

Ummm...
Eliseo no he probado tu código pero creo no va...
Me temo que no es tan simple la cosa. Porque lo que dice Fernando es dado el número en real "normalizado a horas" (por darle un nombre  :p ) obtener su expresión en formato hh:mm.

De allí que, por ejemplo:

4.25 son las 04:15
6.5 son las 06:30
17.75 son las 17:45

Es decir, donde la parte entera corresponde a las horas, mientras que la decimal a los minutos.
Tu propuesta toma literalmente el número y asume que la parte decimal es exactamente los minutos.

La otra es diseñar una función propia que extraiga cada parte y haga la conversión de la parte decimal a los minutos.

Saludos,


Tienes razón, pero es que lo hice a la memoria, me faltó precisamente esa parte de la conversión a base 60.  :embarrassed:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   numeroInt: integer;
  4.   numeroStr: string;
  5.   numero: real;
  6. begin
  7.   numero    := strtoFloat(edit1.Text);
  8.   numeroStr := FormatFloat('00.00',Numero);
  9.   numeroStr := StringReplace(numeroStr,'.',':',[rfReplaceAll]);
  10.   numeroInt := strtoint( copy(numeroStr,4,2) ) * 6 div 10;
  11.   numeroStr := copy(numeroStr,1,3) + format('%.*d', [2,numeroInt]);
  12.   showMessage( numeroStr );
  13. end;



Ahora si probado :)

Saludos

Archivos adjuntos


  • 0

#12 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 08 septiembre 2012 - 11:46

Ummm...
Demasiado lio para tan poca cosa me parece amigo.
Digo, yo, ¿Y porqué no obtener directamente las partes en vez de hacer esos pasos?:



delphi
  1. var hh, mm: integer;
  2. begin
  3.   hh := Trunc(Int(TimeInDouble));
  4.   mm := Trunc(Frac(TimeInDouble) * 60);
  5. end;



Lo que resta es presentar el dato en formato cadena. Allí es donde no me sale... Estoy peleado con la función Format(). Intento indicarle que utilice ceros a la izquierda cuando en hh y mm es menor a 10 pero no me sale :p

Saludos,
  • 0

#13 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 08 septiembre 2012 - 11:53

¡Listo! Aquí está mi propuesta:



delphi
  1. function TForm1.DoubleToTime(Time: Double): string;
  2. var hh,mm: Integer;
  3. begin
  4.   hh := Trunc(Int(Time));
  5.   mm := Trunc(Frac(Time) * 60);
  6.   Result := Format('%.2d:%.2d',[hh, mm]);
  7. end;



En 3 líneas de código  ;)

Salutes,
PD: Malo format, me tuviste rompiendo los ****** 40 min para dar con el formato correcto. @ ¡Todo por no ir a la ayuda!  :D :D :D
  • 0

#14 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 10 septiembre 2012 - 01:06

Ummm...
Demasiado lio para tan poca cosa me parece amigo.
Digo, yo, ¿Y porqué no obtener directamente las partes en vez de hacer esos pasos?:


Lo mismo que dije yo, amigo, en el cuarto mensaje del hilo  ^o|

Yo también me encontré con este problema y decidí hacerlo de la manera tradicional, truncando y luego la parte fraccionaria multiplicando por 60


Eso sí, me falto el ejemplo gráfico, pero daba por supuesto que se sabría hacer :p :p

:D :D :D
  • 0

#15 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 10 septiembre 2012 - 12:44


Ummm...
Demasiado lio para tan poca cosa me parece amigo.
Digo, yo, ¿Y porqué no obtener directamente las partes en vez de hacer esos pasos?:


Lo mismo que dije yo, amigo, en el cuarto mensaje del hilo  ^o|

Yo también me encontré con este problema y decidí hacerlo de la manera tradicional, truncando y luego la parte fraccionaria multiplicando por 60


Eso sí, me falto el ejemplo gráfico, pero daba por supuesto que se sabría hacer :p :p

:D :D :D

Ni me dí cuenta de tu post anterior amigo. Publiqué si leer todos los comentarios del hilo... por las prisas.  :( ¿Y si le vamos 50-50 al crédito por los derechos de autor?  :D :D :D

Saludos,
  • 0

#16 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 septiembre 2012 - 12:48

Ni me dí cuenta de tu post anterior amigo. Publiqué si leer todos los comentarios del hilo... por las prisas.  :( ¿Y si le vamos 50-50 al crédito por los derechos de autor?  :D :D :D

Saludos,


Y que a mi que me cague el perro ???? :p :D :D :D

Saludos
  • 0

#17 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 10 septiembre 2012 - 12:52


Ni me dí cuenta de tu post anterior amigo. Publiqué si leer todos los comentarios del hilo... por las prisas.  :( ¿Y si le vamos 50-50 al crédito por los derechos de autor?  :D :D :D

Saludos,


Y que a mi que me cague el perro ???? :p :D :D :D

Saludos

Bueno... está bien... 25% para cada uno: Seoane, Cadetill, Egostar y yo. :p :D

Saludos,
  • 0




IP.Board spam blocked by CleanTalk.