Time Funktion, weche Zeiteinheit?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Time Funktion, weche Zeiteinheit?

Beitrag von thosch »

Hallo!

Ich will die Time Funktion verwenden und frage, in welcher Einheit (Millisekunden, Mikrosekunden oder Sekunden, ... ) diese Zeit ausgegeben wird. In der Doku fehlt diese Angabe.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Socke »

thosch hat geschrieben:Ich will die Time Funktion verwenden und frage, in welcher Einheit (Millisekunden, Mikrosekunden oder Sekunden, ... ) diese Zeit ausgegeben wird. In der Doku fehlt diese Angabe.

Der Datentyp ist TDateTime und ist als Fließkommazahl implementiert. Die Ganzzahlen enthalten die Tage seit dem 30 Dezember 1899 und der Nachkommateil entspricht der Uhrzeit.

https://www.freepascal.org/~michael/articles/datetime/datetime.pdf enthält eine englischsprachige Beschreibung.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: Time Funktion, weche Zeiteinheit?

Beitrag von thosch »

Socke hat geschrieben:
thosch hat geschrieben:Ich will die Time Funktion verwenden und frage, in welcher Einheit (Millisekunden, Mikrosekunden oder Sekunden, ... ) diese Zeit ausgegeben wird. In der Doku fehlt diese Angabe.

Der Datentyp ist TDateTime und ist als Fließkommazahl implementiert. Die Ganzzahlen enthalten die Tage seit dem 30 Dezember 1899 und der Nachkommateil entspricht der Uhrzeit.

https://www.freepascal.org/~michael/articles/datetime/datetime.pdf enthält eine englischsprachige Beschreibung.


Hmm, wie kann ich dann die Millieskunden zählen?

Ich will ungefähr das hier machen:

Code: Alles auswählen

 
 
var
  Startzeit,Endzeit: TDateTime; Verbrauchte_Zeit: TDateTime;
 
begin
  Startzeit := now;
 {
  HIer irgendwas machen
 }
  Endzeit := now;
 
  Verbrauchte_Zeit := Endzeit - StartZeit;
 
  Writeln('Dieser Vorgang hat ',Verbrauchte_Zeit,' gedauert');
end.
 


Erhalte ich die Verbrauchte_Zeit dann in Sekunden, in Millisekunden, in Hundertstel Sekunden oder .... ?

Oder was gibt der Double Wert da an?

Wenn nicht die reine Zeiteinheit, wie kann ich das Ergebnis in Hundertstel-Sekunden, Millisekunden, Mikrosekunden ... umwandeln.

Ich brauche Millisekunden. Mikrosekunden wären aber auch interessant!

Mit Windows API Funktionen nützt mir das hier nichts, ich brauche das unabhängig von der konkreten Plattform und da ist die Time Funktion die unabhängigste, weil zu Object Pascal gehörend.


.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Time Funktion, weche Zeiteinheit?

Beitrag von mse »

thosch hat geschrieben:Erhalte ich die Verbrauchte_Zeit dann in Sekunden, in Millisekunden, in Hundertstel Sekunden oder .... ?

Bitte lies nochmals was Socke schreibt. Die Antwort sollte dann klar sein, auf jeden Fall wenn beide Zeitpunkte nach dem 30.12.1899 liegen.

Horst_h
Beiträge: 72
Registriert: Mi 20. Mär 2013, 08:57

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Horst_h »

Hallo,

zur Verdeutlichung.
Der Nachkommateil ist der Anteil vom Tag.
Wenn Du die Sekunden haben willst dann x 86400 rechnen

Code: Alles auswählen

 
T0 := time;
sleep(1010);
dt:= time-T0;
writeln('Es sind ',dt:10:8,' Tage vergangen');
writeln('Es sind ',dt*24:10:8,' Stunden vergangen');
writeln('Es sind ',dt*24*60:10:8,' Minuten vergangen');
writeln('Es sind ',dt*24*60*60:10:8,' Sekunden vergangen');
writeln('Es sind ',dt*24*60*60*1000:10:8,' Millisekunden vergangen');


Gruß Horst

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: Time Funktion, weche Zeiteinheit?

Beitrag von thosch »

Ok, dann werd ich das mal so machen.

Danke für die Hilfe!

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Timm Thaler »

Horst_h hat geschrieben:Wenn Du die Sekunden haben willst dann x 86400 rechnen


Man darf auch gern die bereits implementierten Funktionen verwenden. Deswegen ist es eine Hochsprache, sonst könnten wir ja gleich Assembler nehmen. ;-)

Code: Alles auswählen

test := Now();
dein Programmteil
WriteLn('Dauer: ' , MilliSecondsBetween(Now(), test));
 


mse hat geschrieben:auf jeden Fall wenn beide Zeitpunkte nach dem 30.12.1899 liegen.


Im Prinzip auch vor diesem Datum, dann ist der Zeitwert einfach negativ.

Code: Alles auswählen

  test := StrToDateTime('31.12.1899 12:00');
  WriteLn(DateTimeToStr(test), ' als Zahl ', test)// ist 1.5
 
  test := StrToDateTime('30.12.1899 12:00');
  WriteLn(DateTimeToStr(test), ' als Zahl ', test)// ist 0.5
 
  test := StrToDateTime('29.12.1899 12:00');
  WriteLn(DateTimeToStr(test), ' als Zahl ', test)// ist -1.5, müsste -0.5 sein


Allerdings ist die Implementierung fehlerhaft, es werden zwar die Tage davor negativ, aber die Stunden positiv dazugezählt, so dass sich sehr eigenartige Effekte ergeben.

Code: Alles auswählen

  WriteLn('um  0:00 ', HoursBetween(StrToDateTime('30.12.1899 0:00'), StrToDateTime('29.12.1899 0:00')))// 24 Stunden
  WriteLn('um  6:00 ', HoursBetween(StrToDateTime('30.12.1899 6:00'), StrToDateTime('29.12.1899 6:00')))// 24 Stunden
  WriteLn('um 12:00 ', HoursBetween(StrToDateTime('30.12.1899 12:00'), StrToDateTime('29.12.1899 12:00')))// 36 Stunden
  WriteLn('um 23:59 ', HoursBetween(StrToDateTime('30.12.1899 23:59'), StrToDateTime('29.12.1899 23:59')))// 59 Stunden


Irgendwie sollte man meinen, dass man 2000 Jahre nach dem Jahr-Null-Problem mal was dazugelernt hätte und solche Fehler nicht mehr passieren...

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Socke »

Die Ursache liegt in der Funktion DateTimeDiff, die nur intern in der Unit DateUtils aufrufbar ist.

Code: Alles auswählen

{
  These functions are declared as approximate by Borland.
  A bit strange, since it can be calculated exactly ?
 
  -- No, because you need rounding or truncating (JM)
}

 
 
Function DateTimeDiff(const ANow, AThen: TDateTime): TDateTime;
begin
  Result:= ANow - AThen;
  if (ANow>0) and (AThen<0) then
    Result:=Result-0.5
  else if (ANow<-1.0) and (AThen>-1.0) then
    Result:=Result+0.5;
end;


Der Grund, warum gerade beim Vergleich von positiven und negativen Zahlen solche Fehler passieren, dürfte darin liegen, dass man keine aufwändigen Funktionsaufrufe und Berechnungen verwenden wollte.
Folgender Code liefert die korrekten Ergebnisse, ist aber auch um den Faktor 10 langsamer sein:

Code: Alles auswählen

Function DateTimeDiff(const ANow, AThen: TDateTime): TDateTime;
var
  t_now, t_then: TDateTime;
begin
  Result:= trunc(ANow) - trunc(AThen);
  t_now := abs(frac(aNow));
  t_then := abs(frac(aThen));
  if t_now >= t_then then
    Result := Result + (t_now - t_then)
  else
      Result := Result + (t_then - t_now);
end;


Inwiefern das Argument, Borland sei auch ungenau noch gilt, mögen andere beurteilen. Unter http://docwiki.embarcadero.com/Librarie ... ursBetween steht nichts mehr von "ungenau". Möglicherweise wurde hier aber auch die Implementierung geändert.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Time Funktion, weche Zeiteinheit?

Beitrag von mse »

Timm Thaler hat geschrieben:
Horst_h hat geschrieben:Wenn Du die Sekunden haben willst dann x 86400 rechnen

Allerdings ist die Implementierung fehlerhaft, es werden zwar die Tage davor negativ, aber die Stunden positiv dazugezählt, so dass sich sehr eigenartige Effekte ergeben.

AFAIK ist das nicht fehlerhaft, bitte lies nochmals was Socke schrieb. ;-)
Socke hat geschrieben:Der Datentyp ist TDateTime und ist als Fließkommazahl implementiert. Die Ganzzahlen enthalten die Tage seit dem 30 Dezember 1899 und der Nachkommateil entspricht der Uhrzeit.

-1.1 entspricht also 1 Tag vor dem 30.12.1899, die Uhrzeit ist 0.1 * 24 Std = 2:24 -> 1899-12-29T02:24.
https://msdn.microsoft.com/en-us/library/82ab7w69.aspx
Vor 1899-12-30 kann man also um die Zeitdifferenz zu bilden nicht einfach die Datums/Zeit-Werte subtrahieren.
Eine typische Microsoft Entscheidung der frühen Stunde. Der Grund ist vermutlich, dass sonst zwischen 1899-12-29 und 1899-12-31 das Vorzeichen über das Datum entscheiden würde und Microsoft Produkte hauptsächlich im Bürobereich eingesetzt wurden, wo ein kontinuierlicher Zeitstrahl kein Bedürfnis ist.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Timm Thaler »

Echt, diesen Schwachsinn haben wir MS zu verdanken? Na, wen wunderts...

Also für Zeitdifferenzen vor 30.12.1899 ist DateTimeUtil kaputt. Sollte das nicht in der Doku stehen?

Code: Alles auswählen

  WriteLn('1 ', HoursBetween(StrToDateTime('30.12.1899 1:00'), StrToDateTime('31.12.1899 23:00')))// soll 46h, ist 46h
  WriteLn('2 ', HoursBetween(StrToDateTime('31.12.1899 23:00'), StrToDateTime('30.12.1899 1:00')))// soll 46h, ist 46h
  WriteLn('3 ', HoursBetween(StrToDateTime('28.12.1899 1:00'), StrToDateTime('29.12.1899 23:00')))// soll 46h, ist 2h
  WriteLn('4 ', HoursBetween(StrToDateTime('29.12.1899 23:00'), StrToDateTime('28.12.1899 01:00')))// soll 46h, ist 2h
 

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Socke »

Timm Thaler hat geschrieben:Echt, diesen Schwachsinn haben wir MS zu verdanken? Na, wen wunderts...

In der SQLite Dokumentation steht ein ganz guter Kommentar:
SQLite Documentation hat geschrieben:The computation of local time depends heavily on the whim of politicians and is thus difficult to get correct for all locales.

und auch im Wikipedia-Artikelt zum Julianischen Kalender, der von SQLite verwendet wird, wird geschrieben:
Wikipedia, Julianisches Datum hat geschrieben:Die wissenschaftliche Zeitmessung benutzt mehrere verschiedene Zeitskalen nebeneinander, welche jeweils für bestimmte Zwecke besonders geeignet sind, z. B. Universal Time „UT“, Internationale Atomzeit „TAI“, Terrestrische Zeit „TT“, Baryzentrische Dynamische Zeit „TDB“ usw.[/code]

Timm Thaler hat geschrieben:Also für Zeitdifferenzen vor 30.12.1899 ist DateTimeUtil kaputt. Sollte das nicht in der Doku stehen?

Willst du nicht einen Bug-Eintrag erstellen?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Timm Thaler »

Socke hat geschrieben:Willst du nicht einen Bug-Eintrag erstellen?


Wollte ich gestern schon machen. Inzwischen bin ich mir nicht mehr sicher, wo genau der Bug liegt: In der "komischen" Stundenrechnung, bei der jeder Tag "rückläufig" ist, also um Mitternacht immer um 48 Stunden springt. Oder in der Differenzbildung, die dieses Springen nicht berücksichtigt, oder falsch, oder was weiß ich.

Aktuell betrifft mich das Thema nicht, ich bin da durch diesen Thread drauf gestoßen. Aber ich finds gruselig, dass einem Sachen, die eigentlich zu den Grundlagen gehören und die ich einfach benutzen will, ohne jede Besonderheit einzeln abzuklären, einem mal eben um die Ohren fliegen können.

Das ist genau so ein Mist wie Now(), welches nach einem Wechsel Sommerzeit / Winterzeit die falsche Zeit zurückgibt, wenn man nicht regelmäßig ReReadLocalTime() aufruft. Häh? Von einer Funktion Now(), die mir laut definition die aktuelle Zeit liefert, erwarte ich, dass sie mir die aktuelle Zeit liefert.

haderlump
Beiträge: 185
Registriert: Fr 18. Jan 2013, 09:29
OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
CPU-Target: Celeron

Re: Time Funktion, weche Zeiteinheit?

Beitrag von haderlump »

Hallo
Wenn du nur verbrauchte millisekunden für einen Vorgang brauchst gibt es die Funktion getTickCount64. Rückmeldung eine LongIntegerzahl.
Diese liefert die Millisekunden seit was weiß ich. Wenn du diese 2 mal aufrufst, kannst du als Differenz die vergangenen Millisekunden bekommen.
Ich mach so bei meiner Modellbahn Geschwindigkeitsmessungen.

Gruß Fritz

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Timm Thaler »

haderlump hat geschrieben:Wenn du nur verbrauchte millisekunden für einen Vorgang brauchst gibt es die Funktion getTickCount64. Rückmeldung eine LongIntegerzahl.
Diese liefert die Millisekunden seit was weiß ich...


Code: Alles auswählen

... but no assumtions should be made as to the interval between the ticks. 


Verstehe ich so, dass die Ticks Millisekunden sein können - oder auch nicht. Kann also auf einem System funktionieren, auf einem anderen nicht.

Code: Alles auswählen

  for k := 1 to 20 do begin
    start := GetTickCount64();
    Sleep(1000);
    ende := GetTickCount64();
    WriteLn(ende - start);
  end;


Gibt unter Windows 1014, unter Linux auf dem Raspi 1000 aus. Scheint also grob zu stimmen... ;-)

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Time Funktion, weche Zeiteinheit?

Beitrag von Socke »

Timm Thaler hat geschrieben:Das ist genau so ein Mist wie Now(), welches nach einem Wechsel Sommerzeit / Winterzeit die falsche Zeit zurückgibt, wenn man nicht regelmäßig ReReadLocalTime() aufruft. Häh? Von einer Funktion Now(), die mir laut definition die aktuelle Zeit liefert, erwarte ich, dass sie mir die aktuelle Zeit liefert.

Aber nur unter Linux/*nix?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten