bug w minutesbetween ??

0

witam mam problem,
uzywajac kodu:

  showmessage(inttostr(minutesbetween(strtotime('11:12'),strtotime('12:11'))));
  showmessage(inttostr(minutesbetween(strtotime('13:12'),strtotime('14:11'))));
  showmessage(inttostr(minutesbetween(strtotime('15:12'),strtotime('16:11'))));
  showmessage(inttostr(minutesbetween(strtotime('17:12'),strtotime('18:11'))));
  showmessage(inttostr(minutesbetween(strtotime('19:12'),strtotime('20:11'))));
  showmessage(inttostr(minutesbetween(strtotime('21:12'),strtotime('22:11'))));

otrzymuje: 58,58,59,58,58,59,

uzywajac:

  a := encodedatetime(2009,10,01,11,12,0,0);
  b := encodedatetime(2009,10,01,12,11,0,0);
  showmessage(inttostr(MinutesBetween(A, B)));
  a := encodedatetime(2009,10,01,13,12,0,0);
  b := encodedatetime(2009,10,01,14,11,0,0);
  showmessage(inttostr(MinutesBetween(A, B)));
  a := encodedatetime(2009,10,01,15,12,0,0);
  b := encodedatetime(2009,10,01,16,11,0,0);
  showmessage(inttostr(MinutesBetween(A, B)));
  a := encodedatetime(2009,10,01,17,12,0,0);
  b := encodedatetime(2009,10,01,18,11,0,0);
  showmessage(inttostr(MinutesBetween(A, B)));
  a := encodedatetime(2009,10,01,19,12,0,0);
  b := encodedatetime(2009,10,01,20,11,0,0);
  showmessage(inttostr(MinutesBetween(A, B)));
  a := encodedatetime(2009,10,01,21,12,0,0);
  b := encodedatetime(2009,10,01,22,11,0,0);
  showmessage(inttostr(MinutesBetween(A, B)));

otrzymuje: 59,58,59,59,58,59

To wszystko nie trzyma sie sensu, w kazdym przypadku wynik powinien byc jednakowy!!

Czemu tak jest? Mam delphi 2009 professional, pzdr

0

tutaj masz rozwiązanie tego problemu :)
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_20299812.html
musisz przelecieć do prawie samego dołu żeby zobaczyć odpowiedzi

0

wiem o tym linku, znalazlem go wczesniej, ale nie ma dostepu do tego forum i nic mi sie nie wyswietla, zatem prosiłbym o przekopiowanie porady?

0
rem napisał(a)

nie ma dostepu do tego forum i nic mi sie nie wyswietla

olesio podał kiedyś rozwiązanie tego problemu.
Trzeba wejść na stronę forum korzystając z linka w Google.
Wpisz w GoogleMinutesBetween() returns varying values
Pierwszy link będzie do tego forum.

0
function MinutesBetweenEx(const ANow, AThen: TDateTime): Int64;  // Integer is enough
begin
Result:=Trunc(0.000001+Abs(Time1-Time2)*1440);
end;

i wytłumaczenie dlaczego tak a nie inaczej
"What is MinutesBetween function?
TDateTime is float type, so rounding isn't absolutely exact. I suppose MinutesBetween looks like:

Result:=Trunc(Abs(Time1-Time2)/1440);"

"It's in DateUtils, and looks like this:

function MinutesBetween(const ANow, AThen: TDateTime): Int64;
begin
Result := Trunc(MinuteSpan(ANow, AThen));
end;

function MinuteSpan(const ANow, AThen: TDateTime): Double;
begin
Result := MinsPerDay * SpanOfNowAndThen(ANow, AThen);
end;

function SpanOfNowAndThen(const ANow, AThen: TDateTime): TDateTime;
begin
if ANow < AThen then
Result := AThen - ANow
else
Result := ANow - AThen;
end;"

0

ja w tym czasie wymysliłem takie rozwiązanie:

a := encodedatetime(2009,10,01,21,12,0,0);
b := encodedatetime(2009,10,01,22,11,0,0);
wynik := inttostr(round(Minutespan(A, B)));

będzie to działać prawidłowo? bo w testowaniu wychodzi ok

0

Ponieważ TDateTime to jest double, a wszystko mnijesze od dnia jest zapisywane w części ułamkowej więc mogą być takie problemy przy konwersji. Przykładowo jak zamienisz Twój kod na

 mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('11:12:00'),strtotime('12:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('13:12:00'),strtotime('14:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('15:12:00'),strtotime('16:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('17:12:00'),strtotime('18:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('19:12:00'),strtotime('20:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('21:12:00'),strtotime('22:11:00'))));

to dostaniesz

59
59
59,0000000000001
59
59
59,0000000000001

natomiast ten błąd jest powodowany przez samo truncate w funkcji MinutesBetween

EDIT: oczywiście sekund nie musisz podawać i na MinutesSpan musisz dać Round bo Trunc też źle tutaj obcina

0
Misiekd napisał(a)

Ponieważ TDateTime to jest double, a wszystko mnijesze od dnia jest zapisywane w części ułamkowej więc mogą być takie problemy przy konwersji. Przykładowo jak zamienisz Twój kod na

 mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('11:12:00'),strtotime('12:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('13:12:00'),strtotime('14:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('15:12:00'),strtotime('16:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('17:12:00'),strtotime('18:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('19:12:00'),strtotime('20:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('21:12:00'),strtotime('22:11:00'))));

to dostaniesz
59
59
59,0000000000001
59
59
59,0000000000001

> 
> natomiast ten błąd jest powodowany przez samo truncate w funkcji MinutesBetween
> 
> EDIT: oczywiście sekund nie musisz podawać i na MinutesSpan musisz dać Round bo Trunc też źle tutaj obcina


dlatego używam jeszcze funkcji <b>round</b>, ale czy to wystarczy zatem?
0
rem napisał(a)
Misiekd napisał(a)

Ponieważ TDateTime to jest double, a wszystko mnijesze od dnia jest zapisywane w części ułamkowej więc mogą być takie problemy przy konwersji. Przykładowo jak zamienisz Twój kod na

 mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('11:12:00'),strtotime('12:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('13:12:00'),strtotime('14:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('15:12:00'),strtotime('16:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('17:12:00'),strtotime('18:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('19:12:00'),strtotime('20:11:00'))));
  mmo1.Lines.Add(FloatToStr(MinuteSpan(strtotime('21:12:00'),strtotime('22:11:00'))));

to dostaniesz
59
59
59,0000000000001
59
59
59,0000000000001

> > 
> > natomiast ten błąd jest powodowany przez samo truncate w funkcji MinutesBetween
> > 
> > EDIT: oczywiście sekund nie musisz podawać i na MinutesSpan musisz dać Round bo Trunc też źle tutaj obcina
> 
> 
> dlatego używam jeszcze funkcji <b>round</b>, ale czy to wystarczy zatem?


sorki, nie doczytałem porady o round, zatem domniemywam ze dobrym tokiem myslenia poszedlem

1 użytkowników online, w tym zalogowanych: 0, gości: 1