AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Timer läuft ab Mitternacht rückwärts
Thema durchsuchen
Ansicht
Themen-Optionen

Timer läuft ab Mitternacht rückwärts

Ein Thema von MisterIXI · begonnen am 1. Sep 2015 · letzter Beitrag vom 2. Sep 2015
Antwort Antwort
Seite 1 von 3  1 23      
MisterIXI

Registriert seit: 4. Jun 2015
15 Beiträge
 
Delphi 7 Personal
 
#1

Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 14:07
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;
  Mit Zitat antworten Zitat
amigage

Registriert seit: 11. Nov 2005
Ort: Leipzig
272 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 14:32
Hallo,

ich würde GetTickCount() abfragen, damit bist Du Mitternachts-unabhängig

Delphi-Quellcode:
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;
Weitere Informationen dazu gibt's hier: http://delphi.about.com/od/windowssh...tstopwatch.htm
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#3

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 14:41
Oder anders: Rechne nicht mit der Uhrzeit sondern mit einer kompletten Zeitangabe (TDateTime).
  Mit Zitat antworten Zitat
MisterIXI

Registriert seit: 4. Jun 2015
15 Beiträge
 
Delphi 7 Personal
 
#4

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 14:44
Hallo,

ich würde GetTickCount() abfragen, damit bist Du Mitternachts-unabhängig



Weitere Informationen dazu gibt's hier: http://delphi.about.com/od/windowssh...tstopwatch.htm
GetTickCount hatte ich anfangs, allerdings wurde der Timer ungenauer (bzw. langsamer), je stärker der PC ausgelastet war, und somit realitv unbrauchbar...
  Mit Zitat antworten Zitat
MisterIXI

Registriert seit: 4. Jun 2015
15 Beiträge
 
Delphi 7 Personal
 
#5

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 15:18
Oder anders: Rechne nicht mit der Uhrzeit sondern mit einer kompletten Zeitangabe (TDateTime).
Ich hab mir das grade mal schnell angeschaut, und es scheint als wären keine Millisekunden da drin? Ich meine auf http://www.delphibasics.co.uk/RTL.as...=StrToDateTime steht zwar dass das Format dd/mm/yyyy hh:mm:ss.[millisekunden] stimmt, allerdings, wenn ich versuche Testweise einer TDateTime variable Werte zuzuweisen, dann krieg ich nur ein fehler von wegen Das ist kein Datum... Wenn ich nach den sekunden z.B. '.412' anfüge geht das genau so wenig...

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...
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#6

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 15:27
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:
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;
In TimeTemp steht jetzt die Zeitdifferenz zwischen "Jetzt" und dem auf T1 zugewiesenen Zeitpunkt.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.158 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 16:00
Ich weiß nicht wie genau du es brauchst. Ist die Regelmäßigkeit wichtig? Dann ist ein Timer (bzw. GetTickCount() ) 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.

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:
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;
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.
  Mit Zitat antworten Zitat
MisterIXI

Registriert seit: 4. Jun 2015
15 Beiträge
 
Delphi 7 Personal
 
#8

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 16:30
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.

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.
  Mit Zitat antworten Zitat
SMO

Registriert seit: 20. Jul 2005
178 Beiträge
 
Delphi XE6 Professional
 
#9

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 16:55
GetTickCount hatte ich anfangs, allerdings wurde der Timer ungenauer (bzw. langsamer), je stärker der PC ausgelastet war, und somit realitv unbrauchbar...
Das sollte nicht passieren. GetTickCount müsste konstant "ticken", aber wie Günther schon sagte, mit einer Auflösung/Genauigkeit von ca. 1/64s (15,625 ms).

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 (timeGetTime) und QueryPerformanceCounter.

Die timeGetTime API ist sehr ähnlich zu GetTickCount, allerdings kann man die Auflösung via timeBeginPeriod auf bis zu 1 ms setzen. Über eine "undokumentierte" ntdll API (NtSetTimerResolution) sogar auf 0.5 ms.
Diese Funktionen (außer natürlich NtSetTimerResolution) findet man in der Standardunit MMSystem (Winapi.MMSystem).

Falls mehr Präzision gebraucht wird, bleibt nur QueryPerformanceCounter in Verbindung mit QueryPerformanceFrequency.

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.


Also das Ganze program ist ein sogenannter "Splitter" für Speedruns eines speziellen Spiels.
Im Prinzip eine Stopuhr...

Ich würde es gerne auf die Millisekunde genau und auch in Echtzeit updaten, also dass man den ganzen Timer hochticken sieht.
Verstehe. Ich hoffe dir ist klar, dass bei einer typischen Bildwiederholfrequenz von 60 Hz ein Zeitabschnitt 1/60 = 16,67 ms beträgt. Also auf die Millisekunde genau messen ist schon drin, jede Millisekunde die Anzeige aktualisieren wäre aber sinnlos.

Geändert von SMO ( 1. Sep 2015 um 16:59 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.158 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Timer läuft ab Mitternacht rückwärts

  Alt 1. Sep 2015, 17:07
Über eine "undokumentierte" ntdll API (NtSetTimerResolution) sogar auf 0.5 ms.
War das nicht der Grund weshalb Google Chrome über Monate (Jahre?) unter Windows die Laptop-Akkus schneller leergesaugt hat als jeder andere Browser?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz