Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980 (https://www.delphipraxis.net/159976-fehler-bei-filedatetodatetime-filegetdate-fhandle-wenn-dateidatum-1980-a.html)

juergen 21. Apr 2011 06:30

Delphi-Version: 2007

Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Guten Morgen,

für das setzen des MP3-Tag "Year" mit dem Datum der MP3-Datei nutze ich nachfolgende Funktion:
Delphi-Quellcode:
function GetFileDate(TheFileName: string): TDateTime;
var
  FHandle: integer;
begin
  FHandle := FileOpen(TheFileName, 0);
  try
    Result := FileDateToDateTime(FileGetDate(FHandle));
  finally
    FileClose(FHandle);
  end;
end;
Allerdings erscheint bei Dateien die älter als 01.01.1980 sind nachfolgende Fehlemeldung:
"Ungültiges Argument zum Codieren des Datums"

Eine oder beide Delphi-Funktionen scheinen somit nicht einsetzbar, allerdings ist in der Delphi-Hilfe nichts dazu geschrieben.

Gibt es hierfür eine Alternative?

Danke schon mal vorab!

daywalker9 21. Apr 2011 06:58

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Mit FileAge solltest Du auch ein Datum < 1980 auslesen können

Delphi-Quellcode:
 
Result := FileDateToDateTime(FileAge(FileName));

juergen 21. Apr 2011 07:11

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Hallo daywalker9,

danke für deinen Antwort.
Die Verwendung von FileAge erzeugt leider dieselbe Fehlermeldung.

himitsu 21. Apr 2011 07:11

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Zitat:

Eine oder beide Delphi-Funktionen scheinen somit nicht einsetzbar, allerdings ist in der Delphi-Hilfe nichts dazu geschrieben.
Wenn man diese Funktionen mal getrennt untersucht, dann könnte man das "Eine von Beiden" eingrenzen.

PS: FileDate ist nunmal ein Wert Typ, der Datumswerte seit 1.1.1980 referenziert ... in der Definition sind dann eben keine negativen Werte vorgesehn, bzw. das ist ein Word und kein Integer :stupid:
Wie können denn im Windows Dateien existieren, welche älter als das OS sind, womit man sie erst erstellen konnte. Das Henne-Ei-Problem :zwinker:

PS: Ab Mitte 2159 wird es wieder Probleme geben.

Satty67 21. Apr 2011 07:37

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Zitat:

Zitat von himitsu (Beitrag 1096303)
PS: Ab Mitte 2159 wird es wieder Probleme geben.

Hab' mal im Kalender ein rotes X reingeschrieben.

Wenn ich das richtig lese, dann gibt Windows auch den 1.1.1980 zurück, wenn die Datei nicht existiert (oder Handle ungültig). Also müsste es Ok sein, wenn man bei einer Exception (bei konvertieren in TDateTime) einfach TDateTime auf 0 und damit 1.1.1980 setzt. Wie himitsu ja geschrieben hat, wäre ein älteres Datei-Datum sowieso ein Datum, das es nicht geben kann.

juergen 21. Apr 2011 07:48

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
@himitsu,

danke für deine Erläuterungen.

Zitat:

Zitat von himitsu
Wie können denn im Windows Dateien existieren, welche älter als das OS sind...

Z.B. kann man mit dem Total Commander das Dateidatum setzen.
Bei MP3-Dateien kommmt der Anwender schon mal auf die Idee das Filedatum auf das Erscheinungsjahr des Liedes zu setzen, da auch einige MP3-Player die Lieder sortiert nach Dateidatum anzeigen können.


Ps.: ein kleiner Hinweis in der Hilfe wäre schon sinnvoll, zumindest für Anfänger wie mich, denen nicht auf Anhieb diese Thematik sofort klar ist.

samso 21. Apr 2011 07:49

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Ich benutze Windows.GetFileTime. Diese Funktion liefert eine Zeit ab 1601 mit einer Auflösung von 100ns. Allerdings muss man sich da zunächst einen ganzen Wald von Funktionen drum herum bauen, weil die Funktion zunächst mal die Zeit als UTC liefert. Die Zeit muss zunächst in die lokale Zeit umgerechnet werden. Danach kann man mit FiletimeToSystemTime die Zeit in ein brauchbares Format umwandeln. Systemtime ist ein Record welches Tag,Monat,Jahr usw. enthält. Damit kann man dann ganz gut weiterarbeiten.
Die Funktionen die bei Delphi benutzt werden, stammen noch aus DOS-Zeiten (bzw. sind dazu kompatibel) und sind schon seit Jahrzehnten veraltet.

Delphi-Quellcode:
var
FileAge: TFiletime;
SystemTime: TSYSTEMTIME;
begin
  GetFileTime(Handle, nil, nil, @FileAge);
  FileTimeToLocalFileTime(FileAge, FileAge);
  FiletimeToSystemTime(FileAge, SystemTime);
  EncodeDate(SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay);
  ...
end;

Blup 21. Apr 2011 08:13

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Code:
Format des Zeitstempels

Bit     Inhalt
-------------------
00-04   Sekunde / 2
05-10   Minute
11-15   Stunde
16-20   Tag
21-24   Monat
25-31   Jahr seit 1980

juergen 21. Apr 2011 09:08

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
@samso,

danke für deine Erklärungen nebst Codebeispiel!
Allerdings bekam ich mit deiner Funktion das Jahr 1899 heraus. Das Datum der Datei war in meinem Testfall der 01.01.1979.

Ich habe es nun folgendermaßen gelöst:
Delphi-Quellcode:
function GetFileDate(TheFileName: string): TDateTime;
var
  SR: TSearchRec;
  SystemTime: TSystemTime;
  NewLastAccessTime: TFileTime;
begin
  Result := 0;
  try
  if FindFirst(TheFileName, faAnyFile, SR) = 0 then try
    if (Windows.FileTimeToLocalFiletime(SR.FindData.ftLastWriteTime, NewLastAccessTime) and
      Windows.FileTimeToSystemTime(NewLastAccessTime, SystemTime)) then
      Result := Encodedate(SystemTime.wYear,
        SystemTime.wMonth,
        SystemTime.wDay) +
        Encodetime(SystemTime.wHour,
        SystemTime.wMinute,
        SystemTime.wSecond,
        SystemTime.wMilliseconds);
  finally
    SysUtils.FindClose(SR)
  end;
end;
@Blup,
danke für den Hinweis.
Wenn in der Delphi-Hilfe bei der Funktionserklärung von FileAge() oder FileGetDate() jeweils dein Hinweis oder ein Verweis auf das Thema "Format Zeitstempel" stehen würde..., ja das wäre dann eine Hilfe. :stupid:

himitsu 21. Apr 2011 09:23

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Gibt es im Delphi 2007 eigentlich schon die neue, überladene Version von Delphi-Referenz durchsuchenFileAge?

FileAge ist eine uralte Funktion, welche das Datum als DOSDateTime liefert

Das format steht dann z.B. da http://msdn.microsoft.com/en-us/library/ms724274.aspx

juergen 23. Apr 2011 10:52

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
@himitsu,
verspätete Antwort:
Nein, die überladene Version von FileAge gibt es in meiner Delphiversion noch nicht.

Satty67 23. Apr 2011 11:13

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Also in meinem D2007prof gibt es die neuere überladene Version. Würde mich wundern, wenn bei Dir nicht...
Delphi-Quellcode:
function FileAge(const FileName: string): Integer; overload; deprecated;
function FileAge(const FileName: string; out FileDateTime: TDateTime): Boolean; overload;
Aber TDateTime bleibt sowieso auf 1899 begrenzt.

juergen 23. Apr 2011 14:44

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
@Satty67,
danke für den Hinweis.
Ich hab's jetzt gesehen, dass das überladene FileAge direkt unter dem alten FileAge in der SysUtils steht...
Ich hatte erwartet, dass NUR die alte Version oder NUR die neue Version zu finden ist und aus diesem Grunde nicht weiter gesucht...:oops:
Sorry.

Delphi-Quellcode:
function FileAge(const FileName: string): Integer; overload;
{$IFDEF MSWINDOWS}
var
  FindData: TWin32FileAttributeData;
  LocalFileTime: TFileTime;
begin
  if GetFileAttributesExFunc(Pointer(Filename), GetFileExInfoStandard, @FindData) then
  begin
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    begin
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi,
        LongRec(Result).Lo) then Exit;
    end;
  end;
  Result := -1;
end;
{$ENDIF}
{$IFDEF LINUX}
var
  st: TStatBuf;
begin
  if stat(PChar(FileName), st) = 0 then
    Result := st.st_mtime
  else
    Result := -1;
end;
{$ENDIF}

{$IFDEF MSWINDOWS}
function FileAge(const FileName: string; out FileDateTime: TDateTime): Boolean;
var
  FindData: TWin32FindData;
  LSystemTime: TSystemTime;
  LocalFileTime: TFileTime;
begin
  Result := False;
  if GetFileAttributesExFunc(Pointer(Filename), GetFileExInfoStandard, @FindData) then
  begin
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    begin
      Result := True;
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      FileTimeToSystemTime(LocalFileTime, LSystemTime);
      with LSystemTime do
        FileDateTime := EncodeDate(wYear, wMonth, wDay) +
          EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
    end;
  end;
end;
{$ENDIF}

Jürgen Paulus 29. Dez 2011 12:26

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Hallo Leute, ich bin gerade dabei, Dateien in einem Verzeichnis automatisch umzunennen und aufsteigend zu nummerieren. Die erste Nummer soll die Datei sein, die zuerst am letzten Tag gespeichert wurde. Also, wenn die zuletzt gespeicherte Datei das Datum "29.12.2011 12:30" hat, dann soll mit der Datei begonnen werden, die am "29.12.2011" zuerst gespeichert wurde.

Wie auch immer, dazu brauche ich das Erstellungsdatum der Datei. Leider funktioniert in Delphi 7 (XP) sowie auch in Delphi 2010 (W7) keine einzige der Methoden bzw. Funktionen die hier in diesem Forum vorgestellt wurden. Bei vielen Dateien bekomme ich immer ein anderes Datum extrahiert als das tatsächliche Erstellungsdatum. Inzwischen habe ich mein Problem mit Hilfe der ShellApi und dem DOS-Aufruf "dir *.* /o-s > myList.txt" gelöst. Schön ist das natürlich nicht, deswegen die Frage an euch, ob ihr noch eine andere Möglichkeit kennt, das Erstellungsdatum einer Datei herauszulesen.

Werte Grüße
Jürgen

himitsu 29. Dez 2011 12:46

AW: Fehler bei FileDateToDateTime(FileGetDate(FHandle)) wenn Dateidatum < 1980
 
Zitat:

Zitat von Jürgen Paulus (Beitrag 1143585)
Leider funktioniert in Delphi 7 (XP) sowie auch in Delphi 2010 (W7) keine einzige der Methoden bzw. Funktionen die hier in diesem Forum vorgestellt wurden. Bei vielen Dateien bekomme ich immer ein anderes Datum extrahiert als das tatsächliche Erstellungsdatum.

Du wertest aber auch das Erstellungsdatum aus? (es gibt ja mehrere Angaben >erstellt/geändert/gelesen< und nicht alle werden von allen Dateisystemen gleichermaßen unterstützt)

Auch sollte man uch Zeitzonen beachten.

Einige Dateisysteme speichern die Zeitzone (inkl. Sommerzeit) und Andere machen das nicht.
Einige Funktionen, zum auslesen der Zeiten, versuchen die Zeitzonen nachträglich rasuszurechnen (egal ob sie überhaupt gespeichert wurde) und Andere machen das nicht.

Zitat:

Leider funktioniert in Delphi 7 (XP) sowie auch in Delphi 2010 (W7) keine einzige der Methoden bzw. Funktionen die hier in diesem Forum vorgestellt wurden.
Was heißt für dich "funktionieren"?

Geben die ein "falsches"/anderes Datum aus,
oder geben sie garkein Datum aus (also absoluten Schrott und nicht im Ansatz stimmige Werte)
oder bekommst du gar Exceptions, bzw. andere Fehlercodes?

Diese Werte kann man softwareseitig auch verändern, weshalb man diese Angaben nicht überbewerten sollte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:42 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