![]() |
Timer läuft ab Mitternacht rückwärts
Hallo zusammen,
So, zu meinem Problem: Ich programmiere seit einiger Zeit an einem speziellen Zeitmesser herum, und bin vom hochzählen eines Timers ziemlich schnell auf das rechnen mithilfe der System zeit umgestiegen. An sich ist die Genauigkeit auf diese Weise wunderbar... Allerdings fängt der timer an, sobald die Systemuhr von 23:59 auf 00:00 umspringt, rückwärts zu laufen. Außerdem sind die ganzen Vergleiche die nebenbei ausgeführt werden natürlich auch hinfällig. Meine Lösungsansätze bisher: (der Timer läuft idR. weniger als 45 Minuten, aber man kann um sicherzugehen eine komplette Stunde als möglichkeit ansehen) 1. Eine Abfrage beim Starten ob die Systemzeit weniger als z.B. eine Stunde vor Mitternacht entfernt ist, und wenn das der Fall ist die ganze Berechnung zu verändern. -> ohne die Uhr des PCs zu beeinflussen (was natürlich nicht gewollt ist) sehe ich hier keinen Sinn. 2. Um 23:59:59 (am besten auf MS genau -> 23:59:59.999) Eine sekundäre Variable zuweisen, und eine neue Zeitmessung starten, auf die dann die Variable jedes mal draufgerechnet wird. Meine Fragen: Gibt es eine bessere Möglichkeit als die Systemzeit abzufragen um eine möglichst genaue Zeitmessung hinzubekommen? Wie funktioniert TTime; wie weist man darauf Werte zu/wie funktionieren diese; Wie fragt man einen genauen Zeitpunkt ab... --> Habt ihr vielleicht einen Link zu einem Guten Eintrag der das ganze erklärt? Vielleicht Ideen für bessere Lösungen des Problems? Mein Code des Timers momentan: Die TTime Variablen werden woanders zu weiteren Berechnungen mehrmals benutzt.
Code:
var
T1, T2, TimeTemp : TTime; implementation {$R *.dfm} procedure TForm1.Timer1Timer(Sender: TObject); begin Label1.Caption:=IntToStr(Zeit); if T1 = 0 then T1 := Time; TimeTemp := MilliSecondsBetween(T1, Time) / 24 / 60 / 60 / 1000; Label1.Caption:=FormatDateTime('nn:ss:zzz', TimeTemp); end; |
AW: Timer läuft ab Mitternacht rückwärts
Hallo,
ich würde GetTickCount() abfragen, damit bist Du Mitternachts-unabhängig :lol:
Delphi-Quellcode:
Weitere Informationen dazu gibt's hier:
var
start, stop, vorbei: cardinal; implementation {$R *.dfm} procedure TForm1.Timer1Timer(Sender: TObject); begin Label1.Caption:=IntToStr(Zeit); if start = 0 then start := GetTickCount; stop := GetTickCount; vorbei:= stop - start; // vergangene Millisekunden end; ![]() |
AW: Timer läuft ab Mitternacht rückwärts
Oder anders: Rechne nicht mit der Uhrzeit sondern mit einer kompletten Zeitangabe (TDateTime).
|
AW: Timer läuft ab Mitternacht rückwärts
Zitat:
|
AW: Timer läuft ab Mitternacht rückwärts
Zitat:
![]() ![]() Es scheint dass TDateTime zumindest theoretisch mein Problem lösen könnte, allerdings habe ich weder herausgefunden wie die Werte gespeichert/zugewiesen/abgerufen werden können, noch wie man den Abstand zweier Werte herausfindet... |
AW: Timer läuft ab Mitternacht rückwärts
TDateTime sind Floatwerte, mit denen Du mit Plus und Minus... rechnen kannst.
Vor dem Komma stehen die Tage, der Nachkommaanteil repräsentiert den Tagesanteil. Mir ist noch nicht so ganz klar geworden, was Du wirklich machen möchtest, versuch es mal hiermit:
Delphi-Quellcode:
In TimeTemp steht jetzt die Zeitdifferenz zwischen "Jetzt" und dem auf T1 zugewiesenen Zeitpunkt.
var
T1, T2, TimeTemp : TDateTime; implementation {$R *.dfm} procedure TForm1.Timer1Timer(Sender: TObject); begin Label1.Caption:=IntToStr(Zeit); if T1 = 0 then T1 := Now; TimeTemp := Now - T1; Label1.Caption:=FormatDateTime('nn:ss:zzz', TimeTemp); end; |
AW: Timer läuft ab Mitternacht rückwärts
Ich weiß nicht wie genau du es brauchst. Ist die Regelmäßigkeit wichtig? Dann ist ein Timer (bzw.
Delphi-Quellcode:
) nicht grade die beste Wahl, denn das ist, glaube ich, nur auf eine 64stel-Sekunde genau. Daher würde ich auch auf den Interval des Timers aufpassen, sodass es am besten glatt aufgeht.
GetTickCount()
Oder ist dir die Erfassung der genauen Zeitspanne wichtig? Dann würde ich nicht mit TDateTime arbeiten, da treten ja schon Rundungsfehler bei Millisekunden auf. Für die Erfassung eines Zeitbereichs gibt es TTimeSpan, da kannst du bequem bis auf Ticks heruntergehen:
Delphi-Quellcode:
Da sieht man auch ganz gut wie es mit einem Timer-Intervall von 750ms immer glautt aufgeht, mit 700 allerdings krumm wird. Kurz nachrechnen, eine 64stel-Sekunde sind 15,625 ms, jepp, geht bei 750 glatt auf, bei 700 nicht.
procedure TForm1.Timer1Timer(Sender: TObject);
var tickCount: DWORD; ticksPassed: Int64; begin tickCount := WinApi.Windows.GetTickCount(); ticksPassed := (tickCount - lastTickCount) * TTimeSpan.TicksPerMillisecond; timePassed := timePassed.Add( TTimeSpan.Create(ticksPassed) ); Caption := String.Format( 'Time passed: %.2d:%.2d:%.2d (%d ms, %d ticks)', [ timePassed.Hours, timePassed.Minutes, timePassed.Seconds, timePassed.MilliSeconds, timePassed.Ticks ]); lastTickCount := tickCount; end; procedure TForm1.FormCreate(Sender: TObject); begin timePassed := TTimeSpan.Zero; lastTickCount := Winapi.Windows.GetTickCount(); end; |
AW: Timer läuft ab Mitternacht rückwärts
Also das Ganze program ist ein sogenannter "Splitter" für Speedruns eines speziellen Spiels.
Im Prinzip eine Stopuhr... Allerdings ist es nicht nur um eine einzelne zeitspanne zu messen sondern auch um einzelne Abschnitte mit früheren Rekorden zu Vergleichen (Beispiel: das Programm ist Für ein altes Mario Kart Spiel und wenn man eine Strecke fertig gefahren hat, drückt man einen Button. Dieser ermittelt erst die Zeit die zwischen dem letzten und diesem Drücken vergangen ist. Dann Vergleicht er diesen Wert (momentan ist die Variable die zeit in MS) mit dem in einer .ini gespeicherten Rekord. der Timer läuft in der zwischenzeit allerdings noch weiter) Ich würde es gerne auf die Millisekunde genau und auch in Echtzeit updaten, also dass man den ganzen Timer hochticken sieht. Ich hatte ganz am anfang das Problem, dass ich einfach einen Timer immer den TickCount hab auslesen lassen für die berechnungen. Da die zeit aber wenn möglich auf Millisekunden genau (mindestens auf sekunden genau) gemessen werden soll, waren die extrem abweichenden Werte Schwachsinn. Dass der Timer ungenau ist, war halt dadurch egal, dass die Systemzeit komplett unabhängig von der Abfragehäufigkeit/Regelmäßigkeit des Timers gearbeitet hat. Und wird auch nicht von der Auslastung von Grafikkarte,CPU, etc... beeinflusst. Die Lösung von naphets scheint auch wunderbar zu funktionieren, ich hab zwar keinen stresstest ausgeführt, aber nach dem wechsel auf 00:00 lief die TDateTime variante weiter wie sie sollte. :thumb: Es lief bis jetzt auch stabil mit der Time variante, und schien auch ziemlich genau. Da war ja nur das Problem mit Mitternacht. Das hätte sich mit der TDateTime variante wohl erledigt... Und selbst wenn es nicht auf die Millisekunde genau funktioniert, ist es nicht allzu schlimm, da die schlussendlich durch die Menschliche eingabe ohnehin ungenau ist. ^^ Ich hau das ganze gleich mal von meinem kleinen Testprogramm in das eigentlich und teste ob es funktioniert. |
AW: Timer läuft ab Mitternacht rückwärts
Zitat:
Bei GetTickCount, sowie anderen Methoden, muss man allerdings auch an den Überlauf denken: GetTickCount liefert die Anzahl der Millisekunden seit letztem Booten des Computers, wenn der also länger als ca. 49,7 Tage am Stück lief, dann fängt der Wert wieder bei 0 an. Es kann also passieren, dass der Endwert eines Messintervalls kleiner ist als der Startwert! Alternativen zu GetTickCount sind Multimedia Timer ( ![]() ![]() Die timeGetTime API ist sehr ähnlich zu GetTickCount, allerdings kann man die Auflösung via ![]() ![]() Diese Funktionen (außer natürlich NtSetTimerResolution) findet man in der Standardunit MMSystem (Winapi.MMSystem). Falls mehr Präzision gebraucht wird, bleibt nur ![]() ![]() Neuere Delphi-Versionen haben übrigens eine System.Diagnostics Unit, in der ein TStopwatch Record zum Zeitmessen implementiert ist. Der benutzt GetTickCount, oder falls verfügbar QueryPerformanceCounter. Zitat:
|
AW: Timer läuft ab Mitternacht rückwärts
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:51 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