![]() |
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 |
AW: Datum/Zeitwerte vergleichen
Zitat:
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: |
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. |
AW: Datum/Zeitwerte vergleichen
So hier in etwa könnte eine Konversion aussehen die himitsu beschreibt:
Delphi-Quellcode:
oder so hier von den
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; ![]()
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; |
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. |
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:
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.
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; 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:
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.
If (trunc(FileTimeToDateTime(Datum1...FindData.ftCreationTime)*24*60*60*1000) <
trunc(FileTimeToDateTime(Datum2...FindData.ftCreationTime)*24*60*60*1000)) then ... Gruß Michael |
AW: Datum/Zeitwerte vergleichen
Zitat:
Da mir bewusst war das es alt ist, hab ich doch von den Schweizern eine gängige standardmethode gepostet. Zitat:
Zitat:
Delphi-Quellcode:
edit
uses DateUtils;
... var Time: TTime; Date: TDate; Time := TimeOf(EinDateTime); Date := DateOf(EinDateTime); Ps:
Delphi-Quellcode:
kann Dir von Nutzen sein
SecondsBetween()
Delphi-Quellcode:
kann Dir von Nutzen sein
DaysBetween()
|
AW: Datum/Zeitwerte vergleichen
Zitat:
Delphi-Quellcode:
[/QUOTE]
uses DateUtils;
... var Time: TTime; Date: TDate; Time := TimeOf(EinDateTime); Date := DateOf(EinDateTime); Ich glaube ja... wohl so dann?
Code:
Zu TTime/TimeOf
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 Werden dort auch die Millisekunden berücksichtig? Michael |
AW: Datum/Zeitwerte vergleichen
Zitat:
|
AW: Datum/Zeitwerte vergleichen
Ok, Danke für die Hilfe
Ich probiere es heut Abend dann mal aus. Michael |
AW: Datum/Zeitwerte vergleichen
Ich hab hier auch noch eine Variante zum Konvertieren, die sieht ähnlich auch wie die von Kodezwerg:
Delphi-Quellcode:
function FileTimeToDateTime(ft: FILETIME): TDateTime;
var st: SYSTEMTIME; lt: FILETIME; begin FillChar(st, SizeOf(st), 0); FillChar(lt, SizeOf(lt), 0); FileTimeToLocalFileTime(ft, lt); FileTimeToSystemTime(lt, st); result := SystemTimeToDateTime(st); end; function DateTimeToFileTime(dt: TDateTime): FILETIME; var st: SYSTEMTIME; lt: FILETIME; begin FillChar(st, SizeOf(st), 0); FillChar(lt, SizeOf(lt), 0); FillChar(result, SizeOf(result), 0); DateTimeToSystemTime(dt, st); SystemTimeToFileTime(st, lt); LocalFileTimeToFileTime(lt, result); end; |
AW: Datum/Zeitwerte vergleichen
Bei
![]() ![]() aber dort leider nur für LastWriteTime. Im TDateTimeInfoRec des ![]() Leider ist die Konvertierungsfunktion intern versteckt und öffentlich nicht zugänglich (manchmal sind die Leute einfach nur saudämlich) und zusätzlich hätte man auch gleich auf die Idee kommen können das Ganze als Helper an TFileTime zu hängen oder direkt in den TFileTime-Record einzubauen. Oder vielleicht mal ein paar der Konvertierungsfunktionen als Helper an TDateTime. Es gibt auch noch sowas wie ![]() |
AW: Datum/Zeitwerte vergleichen
Ich bin nun gerade dabei mit diesem TTime/TimeOf und TDate/DateOf
Da ich hier ja dann mit ...:
Code:
... die Datumswerte vergleiche, habe ich mich gefragt ob ich dies auch so mit einem Datum+Uhrzeit machen kann. Ist ja alles Double. Gleich kam mir die Frage, wieso es dann überhaupt die Funktionen CompareDate/Time und CompareDateTime gibt. In der Hilfe unter "CompareDateTime" habe ich nun folgendes gelesen.
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 Zitat:
Na ich verstehe das mal jetzt gar nicht *lach Ok, dann nimmt man für ein Vergleich zweiter Datum+Uhrzeit Werte dann die Funktion CompareDateTime. Bin ja nicht abgeneigt auch Funktionen zu nutzen *lach Soll ich dann lieber die obigen gespeicherten Werte in D1 und D2 dann lieber auch mit "CompareDate" vergleichen? Und das Ganze auch mit Time/TimeOf (hier dann CompareTime)? Also mal zusammen:
Code:
If D1<D2 usw. oder CompareDate(D1,D2) ?
Var D1,D2 : TDate;
Var T1,T2 : TTime; Var DT1,DT2 : TDateTime; D1 := DateOf(FileTimeToDateTime(Datum1 aus FindData.ftCreationTime)); D2 := DateOf(FileTimeToDateTime(Datum2 aus FindData.ftCreationTime)); T1 := TimeOf(FileTimeToDateTime(Datum1 aus FindData.ftCreationTime)); T2 := TimeOf(FileTimeToDateTime(Datum2 aus FindData.ftCreationTime)); DT1 := FileTimeToDateTime(Datum1 aus FindData.ftCreationTime); DT2 := FileTimeToDateTime(Datum2 aus FindData.ftCreationTime); If T1<T2 usw. oder CompareTime(T1,T2) ? Wegen der Hilfe/Anmerkung bei DT1/DT2 lieber nur mit CompareDateTime(DT1,DT2) ? Gruß Michael |
AW: Datum/Zeitwerte vergleichen
![]() Vielleicht hilft Dir dieses Beispiel weiter.
Delphi-Quellcode:
{
This example shows how to use the TListView's CustomSort method to sort the items in the list using a ordering function. This allows you to sort custom data in the correct order you want. When the user clicks on a column header, the ListView will be sorted by that column. If the user clicks on the same column again, the sort order will be toggled. (***) Dieses Beispiel zeigt die Verwendung der CustomSort Methode einer TListView. Damit kann man z.B Zahlen korrekt (d.h nach ihrer Grösse) sortieren lassen. Wenn der Anwender auf den Kopf einer Spalte klickt, wird die ensprechende Spalte sortiert. Bei nochmaligem Klicken auf dieselbe Spalte wird die Sortierreihenfolge umgekehrt. } { custom sort styles } type TCustomSortStyle = (cssAlphaNum, cssNumeric, cssDateTime); var { variable to hold the sort style } LvSortStyle: TCustomSortStyle; { array to hold the sort order } LvSortOrder: array[0..4] of Boolean; // High[LvSortOrder] = Number of Lv Columns implementation {$R *.DFM} function CustomSortProc(Item1, Item2: TListItem; SortColumn: Integer): Integer; stdcall; var s1, s2: string; i1, i2: Integer; r1, r2: Boolean; d1, d2: TDateTime; { Helper functions } function IsValidNumber(AString : string; var AInteger : Integer): Boolean; var Code: Integer; begin Val(AString, AInteger, Code); Result := (Code = 0); end; function IsValidDate(AString : string; var ADateTime : TDateTime): Boolean; begin Result := True; try ADateTime := StrToDateTime(AString); except ADateTime := 0; Result := False; end; end; function CompareDates(dt1, dt2: TDateTime): Integer; begin if (dt1 > dt2) then Result := 1 else if (dt1 = dt2) then Result := 0 else Result := -1; end; function CompareNumeric(AInt1, AInt2: Integer): Integer; begin if AInt1 > AInt2 then Result := 1 else if AInt1 = AInt2 then Result := 0 else Result := -1; end; begin Result := 0; if (Item1 = nil) or (Item2 = nil) then Exit; case SortColumn of -1 : { Compare Captions } begin s1 := Item1.Caption; s2 := Item2.Caption; end; else { Compare Subitems } begin s1 := ''; s2 := ''; { Check Range } if (SortColumn < Item1.SubItems.Count) then s1 := Item1.SubItems[SortColumn]; if (SortColumn < Item2.SubItems.Count) then s2 := Item2.SubItems[SortColumn] end; end; { Sort styles } case LvSortStyle of cssAlphaNum : Result := lstrcmp(PChar(s1), PChar(s2)); cssNumeric : begin r1 := IsValidNumber(s1, i1); r2 := IsValidNumber(s2, i2); Result := ord(r1 or r2); if Result <> 0 then Result := CompareNumeric(i2, i1); end; cssDateTime : begin r1 := IsValidDate(s1, d1); r2 := IsValidDate(s2, d2); Result := ord(r1 or r2); if Result <> 0 then Result := CompareDates(d1, d2); end; end; { Sort direction } if LvSortOrder[SortColumn + 1] then Result := - Result; end; { The ListView's OnColumnClick event } procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin { determine the sort style } if Column.Index = 0 then LvSortStyle := cssAlphaNum else LvSortStyle := cssNumeric; { Call the CustomSort method } ListView1.CustomSort(@CustomSortProc, Column.Index -1); { Set the sort order for the column} LvSortOrder[Column.Index] := not LvSortOrder[Column.Index]; end; |
AW: Datum/Zeitwerte vergleichen
Immer wieder sieht man Codes, die noch niemand benutzt hat, der sein Programm auch mal debuggt,
mit massenhaft unnötigen Exceptions, welche ständig die Arbeit unterbrechen und jemanden zu einem Mord verleiten (an dem, der das verbrochen hat). ![]() Die uralte TurboPascal-Funktion "Val" ist hier nicht verkehrt, wobei es auch dafür seit Jahrzehnten ein ![]() Code ist allerdings irreführender Bezeichner, denn es ist ja eigentlich die Fehler-Position (ErrPos), aber da liegt der Fehler bei Delphi/Borland/Embaradero und dessen "falscher" Dokumentation/Funktionsdeklaration. |
AW: Datum/Zeitwerte vergleichen
In der Funktion "CompareDates" wird genau das gemacht, was ich angesprochen habe, sprich laut Hilfe (diese eine Anmerkung) soll man die Vergleichsprüfung nicht so machen.
Trotzdem Danke @KodeZwerg für's raussuchen. Michael |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:17 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