![]() |
Rechnen mit Zeiten zur Berechnung von Spesen
Hallo allerseits,
ich möchte eine Anwendung zur Berechnung von Spesen schreiben. Somit muss ich mit Zeiten rechnen und dabei mit einer Genauigkeit auf Minuten. Ich habe jetzt in Delphi mit Zeiten experimentiert und bin dabei auf Probleme durch Rundungen gestoßen. Dabei war die Differenz z.B. von (16:17 - 16:16) = (16:17 - 16:15). Ok, das liegt sicherlich an meiner Funktion, die naiv außer Acht läßt, dass ein Tag nicht 1000 Minuten sondern 1440 Minuten hat. Nun habe ich dieses und andere Foren durchforstet und den Tipp gefunden die TDateTime-Werte mit dem Faktor 1440 = 24*60 in Integer-Werte umzurechnen. Bevor ich jetzt per Zufall auf irgendwelche Probleme stoße, vorab die Frage: Kann es hierbei auch Rundungsprobleme geben? Gruß Peter |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Hm, der Link sagt allerdings nichts über eventuelle Rundungsprobleme beim Rechnen in Minuten. Oder habe ich da etwas nicht richtig verstanden?
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
bei dieser
Delphi-Quellcode:
If YearsBetween(Zeit1, Zeit2) <> 0 Then
S := IntToStr(YearsBetween(Zeit1, Zeit2)) + ' Jahre' Else If MonthsBetween(Zeit1, Zeit2) <> 0 Then S := IntToStr(MonthsBetween(Zeit1, Zeit2)) + ' Monate' Else If WeeksBetween(Zeit1, Zeit2) <> 0 Then S := IntToStr(WeeksBetween(Zeit1, Zeit2)) + ' Wochen ' + IntToStr(Round(Abs(Zeit) - WeeksBetween(Zeit1, Zeit2) * 7)) + ' Tage' Else If DaysBetween(Zeit1, Zeit2) <> 0 Then S := IntToStr(DaysBetween(Zeit1, Zeit2)) + ' Tage ' + TimeToStr(Abs(Zeit) - DaysBetween(Zeit1, Zeit2)) Else S := TimeToStr(Abs(Zeit1 - Zeit2)); Variante passieren keine Rundungsfehler. |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Du willst es minutengenau haben?
Dann wirst du auch keine Rundungfehler bekommen. TDateTime ist millisekundengenau. Du solltest nicht auf eigene Faust rechnen, sondern die bereitgestellten Funktionen nutzen. Öffne mal die Hilfe. Tipp bei der Index-Suche z.B. Now ein. Klicke auf den Beitrag zu der Now-Funktion. Bei der Erklärung zur Now-Funktion z.B. steht da jetzt Kategorie und darunter ein Link "Datum und Uhrzeit". Klicke auf den Link un du erhälst jede Menge Datums/Zeit Funktionen/Prozeduren. Mit diesen solltest du alles was du magst berechnen können. |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Hm, ich habe da noch einen Fehler. Aber das liegt wohl eher daran, wie ich Datum und Uhrzeit zusammenbastele.
Delphi-Quellcode:
Ich habe für Start und Ende vier TDateTimePicker verwendet, um Datum und Uhrzeit getrennt abzubilden. Das Ergebnis ist für:
Ergebnis := MinutesBetween(Trunc(dt1.Date) + Frac(dt3.Time), Trunc(dt2.Date) + Frac(dt4.Time))
'20.12.2007 16:17 und 20.12.2007 16:16' -> 1 '20.12.2007 16:17 und 20.12.2007 16:15' -> 1 Da kann doch irgendwas nicht stimmen. Genau das sind die Rundungsprobleme, die ich fürchte. Hat jemand eine Idee? Gruß Peter |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Das liegt vielleicht daran, dass TDateTime nichts anderes als eine Realzahl ist.
Vielleicht funktioniert es so
Delphi-Quellcode:
Also bei der weiter in der Zukunft liegenden Zeit vorsichtshalber eine Sekunde dazu und bei der anderen eine Sekunde abziehen
Ergebnis := MinutesBetween(Trunc(dt1.Date) + Frac(dt3.Time) + 1 / SecsPerDay, Trunc(dt2.Date) + Frac(dt4.Time) - 1 / SecsPerDay)
MfG Klaus |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Danke, soweit klappt das schon mal.
Ich kann mir dieses seltsame Verhalten nur so erklären, dass Delphi automatisch zu der Uhrzeit, die ich in Minuten angebe, zufällig Millisekunden hinzuaddiert. Könnte das hinkommen? |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
So ungefähr. Eine Sekunde ist ja ein 86400stel, und dafür gibt es in einem TDateTime (Double) nicht immer eine exakte binäre Entsprechung. Da treten in der Praxis dann schon Probleme auf, z.B. bei if t1 = t2 then ... der Vergleich kann False ergeben, selbst wenn beide (Uhr)Zeiten auf die Sekunde gleich sind.
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Ich fand die Idee mit dem Multiplizieren gar nicht so schlecht.
Delphi-Quellcode:
ZeitInMinuten1 := trunc(zeit1 * 1440);
ZeitInMinuten2 := trunc(zeit2 * 1440); Differenz := ZeitInMinuten2 - ZeitInMinuten1; |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Ich werde, wie empfohlen, in Minuten umrechnen.
Ich verwende bei der Eingabe des von- und bis-Zeitpunktes je zwei DateTimePicker für Datum und Uhrzeit. Als Testdaten habe ich für von und bis den selben Zeitpunkt 1.1.2008 00:00 gewählt. Je nach Variante wie ich die Differenz errechne, wird mir ein anderes Ergebnis angezeigt:
Delphi-Quellcode:
Kann mir das jemand erklären. Ich wende doch nur das Kommutativgesetz an. Wo ist mein Denkfehler?
Variante 1:
IntToStr(Round( (Trunc(vonD.Date) + Frac(vonZ.Time)) *1400) <- sollte natürlich 1440 heißen - Round( (Trunc(bisD.Date) + Frac(bisZ.Time)) *1440)) -> Ergebnis -1577920 Variante 2: IntToStr(Round( Trunc(vonD.Date) *1440 + Frac(vonZ.Time) *1400) <- hier auch - Round( Trunc(bisD.Date) *1440 + Frac(bisZ.Time) *1440)) -> Ergbenis 0 gruß Peter |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
M...! Tippfehler! Natürlich muss ich überall mit dem Faktor 1440 und nicht 1400 rechnen. Das war der Fehler!
Außerdem wende ich nicht zu 100% das Kommutativgesetz an, da ich dazwischen noch eine Rundung durchführe. |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Ein Vorschlag:
Delphi-Quellcode:
function DateTimeToMinutes(const aDT : TDateTime) : Integer;
begin Result := Round(aDT * 1440 * 60); Result := Result div 60; end; function MinutesToDateTime(const aMinutes : Integer) : TDateTime; begin Result := aMinutes / 1440; end; // Zeitdifferenz in Minuten ginge dann so: Diff := DateTimeToMinutes((bisD.Date + bisZ.Time) - (vonD.Date + vonZ.Time)); |
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Gute Idee, das Umrechnen in Sekunden beugt sicherlich Rundungsfehler vor.
Zitat:
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Ich dachte, der DatePicker liefert bei .Date wirklich nur den Datumsanteil, und bei .Time nur die Nachkommastellen?
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Nein, leider nicht. Immer beides, allerdings kann man nur den Teil verändern, den man mit der Kind-Eigenschaft eingestellt hat.
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Na das ist ja ein doofes Teil. Jetzt verstehe ich auch, warum Du eine andere Komponente suchst. :) Vielleicht ist ja in der JVCL was dabei? Ich bin leider noch nicht dazu gekommen, mich näher damit zu beschäftigen.
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Man kann das aber umgehen, wenn man Trunc()/Frac() verwendet.
|
Re: Rechnen mit Zeiten zur Berechnung von Spesen
Na, genau das mache ich auch. Ich hatte aber gehofft, es vermeiden zu können.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:35 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