GARANTIR DESCONTO

Fórum Erro em cálculo com hora! #350686

17/12/2007

0

Preciso dividir um determinado tempo em pedaços iguais onde o cliente determina a hora inicial, a hora final e o intervalo, só que o delphi está calculando errado.
Ex: hora inicial = 08:00, hora final = 08:30, intervalo = 15 minutos
Programa:
For I := 1 to Cont + 1 do
Begin
...HoraInicial := IncMinute(HoraInicial, Intervalo); // se der um showmessage aqui, a hora está correta
...If HoraInicial = HoraFinal then
......Break
...Else If HoraInicial > HoraFinal then
......Showmessage(´mensagem´);
End;
Nesta circunstância a resposta está OK, porém se a diferença entre a hora inicial e a hora final for maior que 30 minutos, não dá certo de jeito nenhum.
Aguém sabe o porquê disto?


Edilcimar

Edilcimar

Responder

Posts

17/12/2007

Massuda

Como TDateTime é um ponto flutuante, sempre existe a possibilidade de haver imprecisões nos cálculos. Explique o que seu loop faz.


Responder

Gostei + 0

17/12/2007

Felipeucc

Olá amigo,

Acredito que o erro esteja no For I := 1 to[color=red:4fdd7fb557] Cont + 1[/color:4fdd7fb557] do

Apesar de não ter especificado o que faz esse for, acredito que não precise do + 1 no Cont.

Verifique se é isso ou dê mais detalhes sobre o código.

Mas, dizer o que o Delphi está fazendo errado.... essa foi boa. hehehhe.

Não leve a mau, mas o Delphi fez o que você programou.

Abraços


Responder

Gostei + 0

17/12/2007

Edilcimar

O loop está certo, a conta está certa, eu estou mandando o delphi fazer exatamente aquilo que está escrito e ele está fazendo conta errada.
Quanto ao Cont + 1 eu preciso dele, pois quero ver se o cliente não colocou por exemplo hora incial = 08:00, hora final = 8:50 e intervalo = 15. Se eu colocar apenas o Cont, ele vai até 8:45, mas com Cont + 1 ele vai até 09:00, passando portanto das 08:50 e mostrando para o cliente que a hora final está errada pois 50 minutos não é divisível por 15 minutos!
Coloque o meu código num form e execute para ver se dá certo!


Responder

Gostei + 0

17/12/2007

Massuda

Mas de onde vem o Cont? Pelo que entendi, a pessoa informa HoraInicial, HoraFinal e Intervalo, é isso?


Responder

Gostei + 0

17/12/2007

Edilcimar

Este Cont é uma conta que faço para ver quantos consultas caberiam entre a hora inicial e a hora final.
Cont := Trunc(Hora * 24 * 60 / Intervalo); no exemplo de 1 hora e intervalo de 15 minutos isto retorna 4


Responder

Gostei + 0

17/12/2007

Felipeucc

Que valor é atribuido a hora ?
não vi como o resultado disso pode ser 4.


Responder

Gostei + 0

17/12/2007

Massuda

O que afinal está calculando errado?


Responder

Gostei + 0

17/12/2007

Edilcimar

Desculpe esqueci de escrever
Hora := HoraFinal - HoraInicial


Responder

Gostei + 0

17/12/2007

Felipeucc

Amigo,
Aconselho que dê uma estudada na Library DateUtils (pode ser acessada pelo help do Delphi). Lá você encontrará várias funções que podem dar uma simplificada no seu código.

Exemplo: Substitua o código que atribui valor a sua variavel cont por
MinutesBetween(DateTimePicker2.DateTime, DateTimePicker1.DateTime);

Faça uma verificação de Cont div Intervalo <> 0 then
mensagem que intervalo deve ser divisivel pelo periodo... (algo do tipo)


Responder

Gostei + 0

17/12/2007

Edilcimar

Incialmente eu olhei as funções de hora do help do delphi, e não achei algo a contento. O MinutesBeteween() vai me informar a quantidade de minutos entre uma hora inicial e outra final, o que quero é saber quantos ´pedaços´ de intervalos cabem entre a hora inicial e final, para poder calcular se a hora final informada pelo cliente está correta, conforme informei anteriormente, a estrutura que eu montei não tem erro de lógica, o problema está em:
Hora Inicial = 08:00 - Intervalo = 15 minutos
Hora Final = 08:15 -> ok funciona direito
Hora Final = 08:30 -> ok funciona direito
Hora Final = 08:45 -> erro, a conta não bate mais daqui para frente, qualquer que seja o múltiplo de 15 minutos.
O que quero saber é o porquê o delphi me dá este erro?
Se eu der um showmessage(timetostr(hora)), após cada soma, ela está correta, sem nenhum defeito, porém quando faço comparação com a hora final, apesar do showmessage() mostrar a hora correta, internamente o delphi diz que está errado!


Responder

Gostei + 0

17/12/2007

Felipeucc

O delphi interpreta data e hora com número float onde o valor antes da virgula representa a data e depois da virgula representa a hora. (use o debug) onde o dia 0 equivale a 30/12/1899. E não recomendo o uso de Trunc para cálculo de datas e horas.


Responder

Gostei + 0

17/12/2007

Edilcimar

Se você reparar, vai ver que uso Trunc não para fazer conta com horas, mas para calcular o Cont (quantidade de intervalos no período), portanto aí não importa se uso trunc ou div, eu pego inicialmente a hora inicial e final de 2 maskedit, já dei showmessage() em cada linha, tudo que é mostrado na tela está correto, pode ser que o erro seja de arredondamento, mas se o erro existe, por que ele não aparece no showmessage()? Outra coisa, se existe erro de arredondamento o que devo usar? DecodeDate e depois EncodeDate para fazer as comparações?
E se fizer isto ainda assim não vai continuar a haver erro de arredondamento?


Responder

Gostei + 0

17/12/2007

Edilcimar

segue o código completo com comentário
procedure TForm19.MaskEdit8Exit(Sender: TObject);
Var I, Consultas : Word;
begin
...HoraInicial := StrToTime(MaskEdit1.Text);
...MaskEdit8.Color := clWhite;
...Try
......If Trim(MaskEdit8.Text) <> ´:´ then
.........HoraFinal := StrToTime(MaskEdit8.Text);
...Except
......ShowMessage(´Esta não é uma hora válida´);
......MaskEdit8.SetFocus;
...End;
...Hora := HoraFinal - HoraInicial;
...If Hora <= 0 then
...Begin
......ShowMessage(´Horário final tem que ser maior que horário inicial´);
......MaskEdit8.SetFocus;
...End;
...Consultas := Trunc(Hora * 24 * 60 / Intervalo);
...For I := 1 to Consultas + 1 do
...Begin
......HoraInicial := IncMinute(HoraInicial, Intervalo);
......If (HoraInicial = HoraFinal) then
.........Break
......Else If (HoraInicial > HoraFinal) then
......Begin
.........ShowMessage(FormatDateTime(´hh:mm:ss:zzz´, horainicial) + ´ ´ + FormatDateTime(´hh:mm:ss:zzzz´, horafinal)); //////// se a diferença for de 45 minutos ou mais aqui mostra a hora com até os milisegundos iguais, isto foi colocado apenas para efetuar comparação de tempo
.........ShowMessage(´A divisão de tempo entre hora inicial´ + #13 + 10 + ´e hora final, em função do intervalo,´ + 13 + 10 + ´está errada, refaça as contas´);
.........MaskEdit8.SetFocus;
......End;
...End;
end;

O intervalo de tempo usado foi 15 minutos, hora inicial 08:00 (mas pode ser qualquer uma), se hora final for múltiplo de 15 mas maior que 30 minutos, dá erro
???????????????????????????????????


Responder

Gostei + 0

17/12/2007

Fknyght

Cara, tente fazer o seguinte
coloque dois maskedits no form, um edit e um memo e tente o codigo abaixo

procedure TForm1.Button1Click(Sender: TObject);
Var HI , HF : TTime; Intervalo : Integer;
begin
  Memo1.Lines.Clear;
  try HI := StrToTime( MaskEdit1.Text ); except HI := 0; end;
  try HF := StrToTime( MaskEdit2.Text ); except HF := 0; end;
  Intervalo := StrToIntDef(Edit1.Text,15);
  
  if ( ( HI <> 0 ) and ( HF <> 0 ) ) then
    Begin
      While HI <= HF do
        Begin
          Memo1.Lines.Add ( TimeToStr( HI ) );
          HI := HI + StrToTime(´00:´ + IntToStr(Intervalo) + ´:00´ );
        End;
    End
  else
    ShowMessage(´Hora inválidas´);
end;


Lembre-se que se você tiver que fazer calculos com data e hora você tem que fazer no formato de data e hora, nao pode colocar valores inteiros ok


Responder

Gostei + 0

17/12/2007

Edilcimar

fknyght, valeu, este teu macete funcionou


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar