Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Datum/Zeitwerte vergleichen (https://www.delphipraxis.net/197868-datum-zeitwerte-vergleichen.html)

MicMic 12. Sep 2018 19:37

Datum/Zeitwerte vergleichen
 
Hallo,
FILETIME, TDateTime, Timestamp...

Meine Quelle ist jedenfalls FILETIME.

Ich möchte 2 Datumswerte vergleichen, mal 2 Datum+Uhrzeit Angaben und nur mal nach 2 Uhrzeiten.
Also welche dann größer oder kleiner ist.

Da wäre es doch einfacher wenn man folgendes macht.
Die Zeitangabe in Int64 umzuwandeln.
Also erst nach String, dann nach Int64

yyyymmdd : nur für Datum
yyyymmddhhnnsszzz : für Datum und Uhrzeit (zzz noch für Millisekunden)
hhnnsszzz : nur für Uhrzeit (zzz noch für Millisekunden)

Also dann zwei Int64er für 2 Werte, die ich dann mit "Wert1 < Wert2" prüfe.

Kann man doch machen oder?

Oder kann ich hier direkt irgendwie FILETIME verwenden um zu vergleichen?
Also dann auch nur mal ne Uhrzeit oder nur ein Datum.

Gruß
Michael

himitsu 12. Sep 2018 19:47

AW: Datum/Zeitwerte vergleichen
 
Zitat:

Also erst nach String, dann nach Int64
Nein!

Wenn ein Zwischentyp, dann einer mit einer besseren Speicherverwaltung.


Aber warum ein Integer mit einem komischen Format?

Such dir einen Zeit-Typen aus, der sich leicht vergleichen kässt.

TimeStamp (ala Linux) oder TDateTime (ala Delphi-Style) sind Zahlen (Linux-TimeStamp und "Date" = Ganzzahl oder TDate/TTime/TDateTime = Fließkommazahl)
und dann nur noch die verschiedenen Typen "einheitlich" da hin konvertieren.



Leider versteckt die Delphi-RTL die einzige Funktion, welche FILETIME (UTC) direkt nach TDateTime (LocalTime) konvertiert so tief, dass da niemand ran kommt.
Aber sonst gibt es dennoch mehrere Funktionen zum Konvertieren dieser Typen.
Und fast alle gehen immer einen dieser Wege:
TFileTime > TSystemTime > TDateTime
TFileTime > TSystemTime > local TSystemTime > TDateTime



PS: FILETIME (DOS: FAT16) ist ein Integer und die FILETILE der aktuellen WinAPI ist eigentlich schon ein UInt64 (ULARGE_INTEGER).
Gut offiziell sagt microsoft, dass man ihn nicht direkt casten soll, aber es geht. :duck:

ghubi01 12. Sep 2018 20:26

AW: Datum/Zeitwerte vergleichen
 
Hallo MicMic,

in der Unit System.DateUtils sind verschiedene Funktionen enthalten.
Z.B.:

- CompareDate
- CompareDateTime

In beiden Fällen werden zwei Zeitangaben auf größer als oder kleiner als oder sind gleich geprüft.

In der Delphi Haupthilfe sind diese Funktionen genauer beschrieben.

KodeZwerg 12. Sep 2018 20:29

AW: Datum/Zeitwerte vergleichen
 
So hier in etwa könnte eine Konversion aussehen die himitsu beschreibt:
Delphi-Quellcode:
function FileTimeToDateTime(FileTime: TFileTime): TDateTime;
var
  LocalTime: TFileTime;
  DOSTime: Integer;
begin
  FileTimeToLocalFileTime(FileTime, LocalTime);
  FileTimeToDosDateTime(LocalTime, LongRec(DOSTime).Hi, LongRec(DOSTime).Lo);
  Result := FileDateToDateTime(DOSTime);
end;
oder so hier von den Schweizern
Delphi-Quellcode:
function FileTimeToDateTime(FileTime: TFileTime): TDateTime;
var
  ModifiedTime: TFileTime;
  SystemTime: TSystemTime;
begin
  Result := 0;
  if (FileTime.dwLowDateTime = 0) and (FileTime.dwHighDateTime = 0) then
    Exit;
  try
    FileTimeToLocalFileTime(FileTime, ModifiedTime);
    FileTimeToSystemTime(ModifiedTime, SystemTime);
    Result := SystemTimeToDateTime(SystemTime);
  except
    Result := Now; // Something to return in case of error
  end;
end;

function DateTimeToFileTime(FileTime: TDateTime): TFileTime;
var
  LocalFileTime, Ft: TFileTime;
  SystemTime: TSystemTime;
begin
  Result.dwLowDateTime := 0;
  Result.dwHighDateTime := 0;
  DateTimeToSystemTime(FileTime, SystemTime);
  SystemTimeToFileTime(SystemTime, LocalFileTime);
  LocalFileTimeToFileTime(LocalFileTime, Ft);
  Result := Ft;
end;

himitsu 12. Sep 2018 21:23

AW: Datum/Zeitwerte vergleichen
 
Sorry, aber DosTime ... echt jetzt?
Der Typ ist so klein und veraltet, dass er nicht im geringsten an die Auflösung aller anderen genannten Typen ran kommt (Datenverlust), außerdem wird er seit jahrzehnten nirgendwo mehr verwendet.
Gut, die fehlenden Millisekunden kann man vielleicht noch verkraften, aber dieser Typ kennt auch keine ungeraden Sekunden.
Und dieser Typ kennt nur 128 Jahre (7 Bit), also von 1980 bis 2107 und dann ist Schluss.
OK, 90 Jahre sind noch lange hin, aber dennoch ma etwas an die Zukunft denken ... ich versuche auch gerade eben für jemanden ein uraltes Programm am Leben zu erhalten (vor fast 20 Jahren installiert, aber jetzt streikt langsam der PC und muß neu gemacht werden ... Firma weg, Entwickler tot, Nachfolger nicht erreichbar usw. ... Delphi 5 lebt :stupid:).

Wenn man etwas neues macht, dann gibt es keinen Grund veralte Dinge zu benutzen.
Und die Rechnenleisung und die Speichergrößen aller Rechner der letzen Jahrzehnte bieten mehr als genug Ressourcen, um mit Int64/Double arbeiten zu können.

MicMic 13. Sep 2018 13:49

AW: Datum/Zeitwerte vergleichen
 
Ihr bringt mich ganz durcheinander :)

Also ich hole mir die Datums/Zeit Werte von TWIN32FindDataW und TWin32FindData.
Das ist ja dann _FILETIME 64 Bit. Wusste nicht, dass es ein altes DOS FILETIME gibt.

Bei den normalen Vergleichs-Funktionen ist mir nicht klar, was die genau machen wenn man nur nach Datum sucht (nicht nach Uhrzeit) oder nur nach Uhrzeit (nicht nach Datum). Deshalb dachte ich, meine Datumswerte speichere ich in String und wandle dies in YYYYMMDD (nur für ein Datum) um. Dann in eine Zahl konvertieren und dann ganz normal vergleichen (Wert1 < Wert2).

Aber was nun? :)

Ich hab jedenfalls ne Funktion (irgendwo aus dem Netz kopiert).
Code:
function FileTimeToDateTime(FileTime: TFileTime): TDateTime;
var
  ModifiedTime: TFileTime;
  SystemTime: TSystemTime;
begin
  Result := 0;
  if (FileTime.dwLowDateTime = 0) and (FileTime.dwHighDateTime = 0) then
    Exit;
  try
    FileTimeToLocalFileTime(FileTime, ModifiedTime);
    FileTimeToSystemTime(ModifiedTime, SystemTime);
    Result := SystemTimeToDateTime(SystemTime);
  except
    Result := Now; // Something to return in case of error
  end;
end;
Damit kann ich ja meine FILETIME ins Delphi TDateTime konvertieren. Wobei man übers "Result := Now;" sich noch mal Gedanken machen sollte. So ein Fallback (ich glaub das nennt man so) ist ja nicht immer gewünscht.
Mit FormatDateTime kann ich mir dann nur das Datum oder auch nur die Uhrzeit rauskopieren. An die Millisekunden komme ich auch ran. Zurückgeliefert bekomme ich dann hier auch ein String. Aber das soll ich ja nicht machen. Wie dann?

Mit einem TDateTime kann ich ja auch "*24*60*60*1000" rechnen

Also als Beispiel:
Code:
 If (trunc(FileTimeToDateTime(Datum1...FindData.ftCreationTime)*24*60*60*1000) <
 trunc(FileTimeToDateTime(Datum2...FindData.ftCreationTime)*24*60*60*1000)) then ...
Das wäre jedenfalls ein Vergleich mit Datum+Uhrzeit. Mir ist nicht ganz klar, wie ich das nur für ein Datum oder nur für eine Uhrzeit angeben muss.

Gruß
Michael

KodeZwerg 13. Sep 2018 14:23

AW: Datum/Zeitwerte vergleichen
 
Zitat:

Zitat von himitsu (Beitrag 1413070)
Sorry, aber DosTime ... echt jetzt?

Ja um so hoch auflösenden Krams ging es hier glaube ich nicht, rein praktikabel.
Da mir bewusst war das es alt ist, hab ich doch von den Schweizern eine gängige standardmethode gepostet.

Zitat:

Zitat von MicMic (Beitrag 1413114)
Ich hab jedenfalls ne Funktion (irgendwo aus dem Netz kopiert).

Oder aus meinem Beitrag oben hehe

Zitat:

Zitat von MicMic (Beitrag 1413114)
Mit einem TDateTime kann ich ja auch "*24*60*60*1000" rechnen

Hilft Dir sowas bei Deinem Vorhaben?
Delphi-Quellcode:
uses DateUtils;

...

var
  Time: TTime;
  Date: TDate;

Time := TimeOf(EinDateTime);
Date := DateOf(EinDateTime);
edit
Ps:
Delphi-Quellcode:
SecondsBetween()
kann Dir von Nutzen sein
Delphi-Quellcode:
DaysBetween()
kann Dir von Nutzen sein

MicMic 13. Sep 2018 14:46

AW: Datum/Zeitwerte vergleichen
 
Zitat:

Zitat von MicMic (Beitrag 1413114)
Mit einem TDateTime kann ich ja auch "*24*60*60*1000" rechnen

Hilft Dir sowas bei Deinem Vorhaben?
Delphi-Quellcode:
uses DateUtils;

...

var
  Time: TTime;
  Date: TDate;

Time := TimeOf(EinDateTime);
Date := DateOf(EinDateTime);
[/QUOTE]

Ich glaube ja... wohl so dann?
Code:
Var D1,D2 : TDate;

D1 := DateOf(FileTimeToDateTime(Datum1 aus FindData.ftCreationTime));
D2 := DateOf(FileTimeToDateTime(Datum2 aus FindData.ftCreationTime));

If D1 < D2 then ... // kleiner
else if D1 > D2 then ... // größer
else ... // gleich
Zu TTime/TimeOf
Werden dort auch die Millisekunden berücksichtig?

Michael

KodeZwerg 13. Sep 2018 14:54

AW: Datum/Zeitwerte vergleichen
 
Zitat:

Zitat von MicMic (Beitrag 1413129)
Zu TTime/TimeOf
Werden dort auch die Millisekunden berücksichtig?

Ja. TimeOf() setzt den internen Datewert dabei auf 0 (irgendwas mit 1899 oder so) und übrig bleibt nur der Zeitanteil.

MicMic 13. Sep 2018 14:55

AW: Datum/Zeitwerte vergleichen
 
Ok, Danke für die Hilfe
Ich probiere es heut Abend dann mal aus.
Michael


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:13 Uhr.
Seite 1 von 2  1 2   

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