Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, warum?) (https://www.delphipraxis.net/34899-trunc-und-ttime-wenn-ttime-%3D-1-gibt-trunc-0-zurueck-warum.html)

Schmufu 29. Nov 2004 21:25


Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, warum?)
 
Hallo,

ich habe folgende Funktion geschrieben, um aus einem TTime (TDateTime) die Stunden und Minuten zu bekommen, und zwar auch dann die stunden wenn es sich um mehr als 24 stunden handelt.

Es Funktioniert auch wunderbar, allerdings gibt die Funktion 0:00 zurück wenn "Zeit" 1 ist, also exakt 24 Stunden.

Wenn ich mir das ganze beim Debuggen anschaue hat "Zeit" den wert 1, allerdings hat "Tage" nach dem Trunc den Wert 0!

Ändere ich den Quelltext auf "Tage := Trunc(1)" (also immer 1 an Trunc) ist Tage auch immer 1.

Irgendwie verstehe ich das nicht. Kann mir da vielleicht jemand auf die Sprünge helfen?

Code:
function TimeToStrInHoursMinutes(Zeit: TTime): String;
var Tage: Integer;
    Stunden, Minuten: String;
begin
  if Zeit >= 0 then
  begin
    Tage := Trunc(Zeit); // Ganzahl des TTime in Tage?!?
    Stunden := IntToStr(24*Tage + StrToInt(FormatDateTime('hh', Zeit - Tage)));
    Minuten := FormatDateTime('nn', Zeit - Tage);
    Result := Stunden+':'+Minuten;
  end
  else
  begin
    Tage := Trunc(Zeit) * (-1);
    Stunden := IntToStr(24*Tage + StrToInt(FormatDateTime('hh', Zeit + Tage)));
    Minuten := FormatDateTime('nn', Zeit + Tage);
    Result := '-'+Stunden+':'+Minuten;
  end;
end;
PS: Die Funktion hätte man vielleicht auch anders schreiben können, verbesserungsvorschläge werden dankbar angenommen ;)

bttb930 29. Nov 2004 21:38

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
TTime enthält soweit ich weiß nur eine ZEIT. Du brauchst TDateTime. 24 Uhr ist TTime-Mäßig halt 0 Uhr.

Leuselator 29. Nov 2004 21:40

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
Will mir nicht den Kopf zerbrechen, deswegen: mach es ordentlich - nutze Delphi-Referenz durchsuchenDecodeTime und Delphi-Referenz durchsuchenDecodeDate - damit klappt es :-)
Gruß

dizzy 29. Nov 2004 21:40

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
Also bei mir klappt's immer. Lediglich bei 0.99999999999999995 wird bei mir mit trunc fälschlicherweise auf 1 getrunct, aber das liegt halt an der begrenzten Genauigkeit. 1 wird bei mir immer 1. :gruebel:

dizzy 29. Nov 2004 21:44

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
Zitat:

Zitat von bttb930
TTime enthält soweit ich weiß nur eine ZEIT. Du brauchst TDateTime. 24 Uhr ist TTime-Mäßig halt 0 Uhr.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  t: TTime;
begin
  t := 1;
  Edit1.Text := IntToStr(trunc(t));
end;
In meinem Edit steht eine "1"... Ist allerdings die Frage woher dieser Wert stammt, und wie er dort behandelt wird! Es kann durchaus sein dass die Funktion die die Variable füllt, bei einem TTime-Wert darauf achtet, dass der Vorkommaanteil immer 0 ist.

Sharky 30. Nov 2004 08:11

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
Zitat:

Zitat von bttb930
TTime enthält soweit ich weiß nur eine ZEIT. Du brauchst TDateTime. 24 Uhr ist TTime-Mäßig halt 0 Uhr.

TTime ist das selbe wie TDate oder TDateTime!!! Es gibt keinen Unterschied zweichen den drei Deklarationen.

Zitat:

Zitat von dizzy
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  t: TTime;
begin
  t := 1;
  Edit1.Text := IntToStr(trunc(t));
end;
In meinem Edit steht eine "1"... Ist allerdings die Frage woher dieser Wert stammt.

Naja, da Du t := 1 schreibst ist doch auch klar das in deinem Edit eine 1 steht.

dizzy 30. Nov 2004 10:41

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
Zitat:

Zitat von Sharky
TTime ist das selbe wie TDate oder TDateTime!!! Es gibt keinen Unterschied zweichen den drei Deklarationen.
[...]
Naja, da Du t := 1 schreibst ist doch auch klar das in deinem Edit eine 1 steht.

Deswegen ja mein kleiner Einschub oben, der im Grunde aussagen sollte, dass zwar der Datentyp identisch ist, aber evtl. die Funktion die die Variable befüllt bei einer Deklaration als TTime darauf achtet keine Werte >= 1 zu schreiben. Geht zwar im Typ, macht aber die Funktion nicht.
Wurd das oben nicht klar? :angel2:

Und da ich den Wert von Hand, und nicht durch eine der Zeit-Funtionen von Delphi setze, komme ich tatsächlich auf 1.

Schmufu 30. Nov 2004 12:08

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
Also erstmal vielen dank für die Vorschläge.

Momentan bin ich auf der Arbeit und kann leider nicht testen, es ist aber so, dass der TTime-Wert der übergeben wird folgendermaßen erstellt wird:

Zuerst wird mit "EncodeTime(0,0,0,0)" die Variable auf "null" gesetzt, dann werden die Eingaben des Nutzers mit "StrToTime" umgewandelt und zu der TTime-Variablen addiert.

Zu der Vermutung das es nicht möglich ist Werte größer 1 zuzuweisen, kann ich nicht zustimmen, da auch Stunden im Format 38:15, 128:37 usw fehlerfrei funktionieren. Wo ich mir momentan nicht sicher bin ist ob auch Werte von 2 (48 Std), 3 (72 Std) usw nicht funktionieren, ich bin aber der meinung das diese Werte funktionieren.

Sharky 30. Nov 2004 12:15

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
Zitat:

Zitat von Schmufu
...Zu der Vermutung das es nicht möglich ist Werte größer 1 zuzuweisen, kann ich nicht zustimmen....

Also mal so aus dem Kopf getippt:
Delphi-Quellcode:
var
  t1 : TTime;
  t2 : TTime;
begin
  t1 := EncodeTime(12,0,0,0); // t1 "ist jetzt" 12 Uhr am 30. Dezember 1899
  t2 := t1 + 1; // t2 ist jetzt 12 Uhr am folge Tag von t1
end;

Schmufu 30. Nov 2004 15:53

Re: Trunc und TTime (Wenn TTime = 1 gibt Trunc 0 zurück, war
 
So, ich habe jetzt ein kleines Beispiel welches leicht nach zu vollziehen sein sollte, und wo genau der Fehler auftritt den ich meine!

Code:
function TForm1.TimeToStrInHoursMinutes(Zeit: TTime): String;
var Tage: Integer;
    Stunden, Minuten: String;
begin
  if Zeit >= 0 then
  begin
    Tage := Trunc(Zeit); // Ganzahl des TTime in Tage?!?
    Stunden := IntToStr(24*Tage + StrToInt(FormatDateTime('hh', Zeit - Tage)));
    Minuten := FormatDateTime('nn', Zeit - Tage);
    Result := Stunden+':'+Minuten;
  end
  else
  begin
    Tage := Trunc(Zeit) * (-1);
    Stunden := IntToStr(24*Tage + StrToInt(FormatDateTime('hh', Zeit + Tage)));
    Minuten := FormatDateTime('nn', Zeit + Tage);
    Result := '-'+Stunden+':'+Minuten;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var t1, t2: TTime;
    i: Integer;
begin
  t1 := EncodeTime(0,0,0,0); // t1 = 0
  t2 := EncodeTime(1,0,0,0); // t2 wert von 1 Stunde

  for i := 1 to 24 do // 24 * 1 ist 24 !
    t1 := t1 + t2;

  ShowMessage(FloatToStr(t1)); // Gibt in der Message "1" aus
  ShowMessage(TimeToStrInHoursMinutes(t1)); // Zeigt "0:00" an ! Warum ?
end;
Klickt man auf Button1 kommt zuerst eine "1" und danach "0:00"! Nach meiner Meinung sollte aber "24:00" kommen.
Setzt man vor die beiden ShowMessage noch folgende Zeile wird auch "24:00" angezeigt
Code:
t1 := t1 + 0.0000000001; // liegt irgendwo im Sekunden/Millisekunden bereich
Spielt man ein wenig mit der Schleife und stellt sie auf 48 statt 24 funktioniert alles, bei 72 zeigt er dann 48:00, obwohl t1 = 3 ist, und schließlich bei 96 zeigt er 72:00 an und t1 = 3,99...!

Schaut man sich bei einer Schleifenzahl von 72 das ganze im Debugger an sagt er das "Zeit" 3 ist aber nach dem trunc erhält "Tage" den wert 2.

Dass das ganze irgendwie mit Rundungsfehlern und ungenügender Genauigkeit zu tun hat kann ich mir schon vorstellen, aber auf die Minute genau sollte das doch eigentlich schon sein. Oder irre ich mich da?


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz